@things-factory/organization 10.1.232 → 10.1.234

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 (42) hide show
  1. package/dist-client/component/approval-line-edit.d.ts +9 -0
  2. package/dist-client/component/approval-line-edit.js +8 -0
  3. package/dist-client/component/approval-line-edit.js.map +1 -1
  4. package/dist-client/component/approval-line-items-editor.js +2 -2
  5. package/dist-client/component/approval-line-items-editor.js.map +1 -1
  6. package/dist-client/component/approval-line-templates-manager.js +2 -1
  7. package/dist-client/component/approval-line-templates-manager.js.map +1 -1
  8. package/dist-client/component/assignees-editor.js +2 -1
  9. package/dist-client/component/assignees-editor.js.map +1 -1
  10. package/dist-client/component/recipients-editor.js +2 -1
  11. package/dist-client/component/recipients-editor.js.map +1 -1
  12. package/dist-client/tsconfig.tsbuildinfo +1 -1
  13. package/dist-server/ai-entry/organization-entry-rules.js +3 -3
  14. package/dist-server/ai-entry/organization-entry-rules.js.map +1 -1
  15. package/dist-server/service/approval-line/approval-line-mutation.js +7 -5
  16. package/dist-server/service/approval-line/approval-line-mutation.js.map +1 -1
  17. package/dist-server/service/department/department-mutation.js +2 -1
  18. package/dist-server/service/department/department-mutation.js.map +1 -1
  19. package/dist-server/service/department/department-parent.js +3 -2
  20. package/dist-server/service/department/department-parent.js.map +1 -1
  21. package/dist-server/service/domain-reference.d.ts +1 -1
  22. package/dist-server/service/domain-reference.js +2 -2
  23. package/dist-server/service/domain-reference.js.map +1 -1
  24. package/dist-server/service/employee/employee-control-no.d.ts +12 -0
  25. package/dist-server/service/employee/employee-control-no.js +27 -0
  26. package/dist-server/service/employee/employee-control-no.js.map +1 -0
  27. package/dist-server/service/employee/employee-day.js +4 -1
  28. package/dist-server/service/employee/employee-day.js.map +1 -1
  29. package/dist-server/service/employee/employee-mutation.js +12 -3
  30. package/dist-server/service/employee/employee-mutation.js.map +1 -1
  31. package/dist-server/service/employee-profile/employee-profile-query.js +3 -2
  32. package/dist-server/service/employee-profile/employee-profile-query.js.map +1 -1
  33. package/dist-server/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +7 -7
  35. package/tests/assignees-editor-no-role.test.ts +2 -2
  36. package/tests/refusals-in-korean.test.ts +48 -0
  37. package/translations/en.json +13 -1
  38. package/translations/es.json +13 -1
  39. package/translations/ja.json +13 -1
  40. package/translations/ko.json +13 -1
  41. package/translations/ms.json +13 -1
  42. package/translations/zh.json +13 -1
@@ -120,10 +120,10 @@ function changedParentId(values) {
120
120
  }
121
121
  /** checkedParent's refusal as a verdict - any other error (the database, say) is not a verdict and is passed on. */
122
122
  function parentVerdictOf(error) {
123
- const message = String(error?.message ?? '');
124
- if (/cannot be placed under itself/.test(message))
123
+ const code = error?.code;
124
+ if (code === 'department-parent-loop')
125
125
  return 'loop';
126
- if (/parent department not found/.test(message))
126
+ if (code === 'department-parent-not-found')
127
127
  return 'not-found';
128
128
  return undefined;
129
129
  }
@@ -1 +1 @@
1
- {"version":3,"file":"organization-entry-rules.js","sourceRoot":"","sources":["../../server/ai-entry/organization-entry-rules.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The rules a proposed department or employee row passes - pure, so they are tested without a server.\n * The targets (organization-entry-targets.ts) read what is already entered and hand it here.\n */\nimport type { EntryIssue, EntryRecord } from './entry-target-shape'\n\ntype Row = { values: Record<string, unknown> }\n\nconst text = (value: unknown) => (typeof value === 'string' || typeof value === 'number' ? String(value).trim() : '')\n\n/** A reference the row still names in words - `{ text }` - because the query found nothing (or several). */\nconst unresolvedText = (value: unknown) => (value && typeof value === 'object' && typeof (value as any).text === 'string' ? (value as any).text.trim() : '')\n\n/** Only the fields given, and a reference as its id alone - `{ id }` is what the mutation's ObjectRef takes. */\nexport function inputOf(values: Record<string, unknown>, names: string[], references: string[] = []): Record<string, unknown> {\n const input: Record<string, unknown> = {}\n for (const name of names) {\n if (!(name in values) || values[name] === undefined) continue\n const value = values[name]\n if (references.includes(name)) input[name] = value && typeof value === 'object' && typeof (value as any).id === 'string' ? { id: (value as any).id } : null\n else input[name] = value\n }\n return input\n}\n\n/**\n * A department row against what the domain already has and the other rows of the proposal.\n *\n * Name and 관리번호 are each unique in a domain (ix_department_0, ix_department_1) - one already there keeps the\n * row out, and so does a row that repeats an earlier row of the same proposal (the later one is kept out).\n * Rows are entered one by one in no order the framework promises, so a parent named by another row of the\n * same proposal does not exist yet when this row runs: the row is kept out and the person enters the parent first.\n */\nexport function departmentIssues(rows: Row[], existing: { name?: string | null; controlNo?: string | null }[]): EntryIssue[][] {\n const names = new Set(existing.map(one => text(one.name)).filter(Boolean))\n const codes = new Set(existing.map(one => text(one.controlNo)).filter(Boolean))\n\n return rows.map((row, i) => {\n const issues: EntryIssue[] = []\n const name = text(row.values.name)\n const controlNo = text(row.values.controlNo)\n\n if (name && names.has(name)) issues.push({ field: 'name', code: 'duplicate', messageKey: 'text.organization-entry-department-name-exists', blocking: true })\n if (controlNo && codes.has(controlNo))\n issues.push({ field: 'controlNo', code: 'duplicate', messageKey: 'text.organization-entry-department-control-no-exists', blocking: true })\n\n const earlier = rows.slice(0, i)\n if (\n (name && earlier.some(other => text(other.values.name) === name)) ||\n (controlNo && earlier.some(other => text(other.values.controlNo) === controlNo))\n )\n issues.push({ code: 'duplicate-in-proposal', messageKey: 'text.organization-entry-department-repeated', blocking: true })\n\n const parent = unresolvedText(row.values.parent)\n if (parent && rows.some((other, j) => j !== i && (text(other.values.name) === parent || text(other.values.controlNo) === parent)))\n issues.push({ field: 'parent', code: 'parent-in-proposal', messageKey: 'text.organization-entry-department-parent-first', params: { parent }, blocking: true })\n\n return issues\n })\n}\n\n/** An employee row - the 사번 (controlNo) is unique in a domain among the employees not deleted (ix_employee_0). */\nexport function employeeIssues(rows: Row[], existing: { controlNo?: string | null }[]): EntryIssue[][] {\n const codes = new Set(existing.map(one => text(one.controlNo)).filter(Boolean))\n return rows.map((row, i) => {\n const controlNo = text(row.values.controlNo)\n if (!controlNo) return []\n if (codes.has(controlNo)) return [{ field: 'controlNo', code: 'duplicate', messageKey: 'text.organization-entry-employee-exists', blocking: true }]\n if (rows.slice(0, i).some(other => text(other.values.controlNo) === controlNo))\n return [{ field: 'controlNo', code: 'duplicate-in-proposal', messageKey: 'text.organization-entry-employee-repeated', blocking: true }]\n return []\n })\n}\n\n/** The departments a name or a 관리번호 names - exactly, never a piece of it. */\nexport function departmentsNamed(items: { id: string; name?: string | null; controlNo?: string | null }[], said: string): { id: string; label: string }[] {\n const wanted = said.trim().toLowerCase()\n if (!wanted) return []\n return items\n .filter(one => text(one.name).toLowerCase() === wanted || text(one.controlNo).toLowerCase() === wanted)\n .map(one => ({ id: one.id, label: codeAndName(one) }))\n}\n\n/** The records whose every given criterion is a piece of the field - \"영업\" finds 영업1팀 and 영업2팀. */\nexport function matching(records: EntryRecord[], criteria: Record<string, unknown>): EntryRecord[] {\n const given = Object.entries(criteria ?? {}).filter(([, value]) => text(value))\n return records.filter(record => given.every(([name, value]) => text(record[name]).toLowerCase().includes(text(value).toLowerCase())))\n}\n\nexport function codeAndName(record: Record<string, unknown>): string {\n return [text(record.controlNo), text(record.name)].filter(Boolean).join(' · ')\n}\n\n/** What the department's own parent rule (checkedParent) said of a changed parent - read only, before the change runs. */\nexport type ParentVerdict = 'loop' | 'not-found' | undefined\n\n/**\n * A change of a department against the other departments of the domain and the other changes of the card.\n *\n * A new name or 관리번호 another department already has (the record itself excepted) keeps the change out, and so\n * does one an earlier change of the same card gives. A parent that is the department itself or one of its own\n * sub-departments - or one the person cannot see - keeps it out too, as `updateDepartment` would refuse it.\n */\nexport function departmentChangeIssues(\n rows: { id: string; values: Record<string, unknown> }[],\n existing: { id: string; name?: string | null; controlNo?: string | null }[],\n parents: ParentVerdict[] = []\n): EntryIssue[][] {\n return rows.map((row, i) => {\n const issues: EntryIssue[] = []\n const name = 'name' in row.values ? text(row.values.name) : ''\n const controlNo = 'controlNo' in row.values ? text(row.values.controlNo) : ''\n const others = existing.filter(one => one.id !== row.id)\n\n if (name && others.some(one => text(one.name) === name))\n issues.push({ field: 'name', code: 'duplicate', messageKey: 'text.organization-entry-department-name-exists', blocking: true })\n if (controlNo && others.some(one => text(one.controlNo) === controlNo))\n issues.push({ field: 'controlNo', code: 'duplicate', messageKey: 'text.organization-entry-department-control-no-exists', blocking: true })\n\n const earlier = rows.slice(0, i).filter(other => other.id !== row.id)\n if ((name && earlier.some(other => text(other.values.name) === name)) || (controlNo && earlier.some(other => text(other.values.controlNo) === controlNo)))\n issues.push({ code: 'duplicate-in-proposal', messageKey: 'text.organization-entry-department-repeated', blocking: true })\n\n if (parents[i] === 'loop') issues.push({ field: 'parent', code: 'parent-loop', messageKey: 'text.organization-entry-department-parent-loop', blocking: true })\n if (parents[i] === 'not-found') issues.push({ field: 'parent', code: 'parent-not-found', messageKey: 'text.organization-entry-department-parent-not-found', blocking: true })\n\n return issues\n })\n}\n\n/** The id of a changed parent - `{ id }` when the reference was resolved; anything else is not asked about. */\nexport function changedParentId(values: Record<string, unknown>): string | undefined {\n const parent = values.parent\n return parent && typeof parent === 'object' && typeof (parent as any).id === 'string' ? (parent as any).id : undefined\n}\n\n/** checkedParent's refusal as a verdict - any other error (the database, say) is not a verdict and is passed on. */\nexport function parentVerdictOf(error: unknown): ParentVerdict {\n const message = String((error as any)?.message ?? '')\n if (/cannot be placed under itself/.test(message)) return 'loop'\n if (/parent department not found/.test(message)) return 'not-found'\n return undefined\n}\n"]}
1
+ {"version":3,"file":"organization-entry-rules.js","sourceRoot":"","sources":["../../server/ai-entry/organization-entry-rules.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The rules a proposed department or employee row passes - pure, so they are tested without a server.\n * The targets (organization-entry-targets.ts) read what is already entered and hand it here.\n */\nimport type { EntryIssue, EntryRecord } from './entry-target-shape'\n\ntype Row = { values: Record<string, unknown> }\n\nconst text = (value: unknown) => (typeof value === 'string' || typeof value === 'number' ? String(value).trim() : '')\n\n/** A reference the row still names in words - `{ text }` - because the query found nothing (or several). */\nconst unresolvedText = (value: unknown) => (value && typeof value === 'object' && typeof (value as any).text === 'string' ? (value as any).text.trim() : '')\n\n/** Only the fields given, and a reference as its id alone - `{ id }` is what the mutation's ObjectRef takes. */\nexport function inputOf(values: Record<string, unknown>, names: string[], references: string[] = []): Record<string, unknown> {\n const input: Record<string, unknown> = {}\n for (const name of names) {\n if (!(name in values) || values[name] === undefined) continue\n const value = values[name]\n if (references.includes(name)) input[name] = value && typeof value === 'object' && typeof (value as any).id === 'string' ? { id: (value as any).id } : null\n else input[name] = value\n }\n return input\n}\n\n/**\n * A department row against what the domain already has and the other rows of the proposal.\n *\n * Name and 관리번호 are each unique in a domain (ix_department_0, ix_department_1) - one already there keeps the\n * row out, and so does a row that repeats an earlier row of the same proposal (the later one is kept out).\n * Rows are entered one by one in no order the framework promises, so a parent named by another row of the\n * same proposal does not exist yet when this row runs: the row is kept out and the person enters the parent first.\n */\nexport function departmentIssues(rows: Row[], existing: { name?: string | null; controlNo?: string | null }[]): EntryIssue[][] {\n const names = new Set(existing.map(one => text(one.name)).filter(Boolean))\n const codes = new Set(existing.map(one => text(one.controlNo)).filter(Boolean))\n\n return rows.map((row, i) => {\n const issues: EntryIssue[] = []\n const name = text(row.values.name)\n const controlNo = text(row.values.controlNo)\n\n if (name && names.has(name)) issues.push({ field: 'name', code: 'duplicate', messageKey: 'text.organization-entry-department-name-exists', blocking: true })\n if (controlNo && codes.has(controlNo))\n issues.push({ field: 'controlNo', code: 'duplicate', messageKey: 'text.organization-entry-department-control-no-exists', blocking: true })\n\n const earlier = rows.slice(0, i)\n if (\n (name && earlier.some(other => text(other.values.name) === name)) ||\n (controlNo && earlier.some(other => text(other.values.controlNo) === controlNo))\n )\n issues.push({ code: 'duplicate-in-proposal', messageKey: 'text.organization-entry-department-repeated', blocking: true })\n\n const parent = unresolvedText(row.values.parent)\n if (parent && rows.some((other, j) => j !== i && (text(other.values.name) === parent || text(other.values.controlNo) === parent)))\n issues.push({ field: 'parent', code: 'parent-in-proposal', messageKey: 'text.organization-entry-department-parent-first', params: { parent }, blocking: true })\n\n return issues\n })\n}\n\n/** An employee row - the 사번 (controlNo) is unique in a domain among the employees not deleted (ix_employee_0). */\nexport function employeeIssues(rows: Row[], existing: { controlNo?: string | null }[]): EntryIssue[][] {\n const codes = new Set(existing.map(one => text(one.controlNo)).filter(Boolean))\n return rows.map((row, i) => {\n const controlNo = text(row.values.controlNo)\n if (!controlNo) return []\n if (codes.has(controlNo)) return [{ field: 'controlNo', code: 'duplicate', messageKey: 'text.organization-entry-employee-exists', blocking: true }]\n if (rows.slice(0, i).some(other => text(other.values.controlNo) === controlNo))\n return [{ field: 'controlNo', code: 'duplicate-in-proposal', messageKey: 'text.organization-entry-employee-repeated', blocking: true }]\n return []\n })\n}\n\n/** The departments a name or a 관리번호 names - exactly, never a piece of it. */\nexport function departmentsNamed(items: { id: string; name?: string | null; controlNo?: string | null }[], said: string): { id: string; label: string }[] {\n const wanted = said.trim().toLowerCase()\n if (!wanted) return []\n return items\n .filter(one => text(one.name).toLowerCase() === wanted || text(one.controlNo).toLowerCase() === wanted)\n .map(one => ({ id: one.id, label: codeAndName(one) }))\n}\n\n/** The records whose every given criterion is a piece of the field - \"영업\" finds 영업1팀 and 영업2팀. */\nexport function matching(records: EntryRecord[], criteria: Record<string, unknown>): EntryRecord[] {\n const given = Object.entries(criteria ?? {}).filter(([, value]) => text(value))\n return records.filter(record => given.every(([name, value]) => text(record[name]).toLowerCase().includes(text(value).toLowerCase())))\n}\n\nexport function codeAndName(record: Record<string, unknown>): string {\n return [text(record.controlNo), text(record.name)].filter(Boolean).join(' · ')\n}\n\n/** What the department's own parent rule (checkedParent) said of a changed parent - read only, before the change runs. */\nexport type ParentVerdict = 'loop' | 'not-found' | undefined\n\n/**\n * A change of a department against the other departments of the domain and the other changes of the card.\n *\n * A new name or 관리번호 another department already has (the record itself excepted) keeps the change out, and so\n * does one an earlier change of the same card gives. A parent that is the department itself or one of its own\n * sub-departments - or one the person cannot see - keeps it out too, as `updateDepartment` would refuse it.\n */\nexport function departmentChangeIssues(\n rows: { id: string; values: Record<string, unknown> }[],\n existing: { id: string; name?: string | null; controlNo?: string | null }[],\n parents: ParentVerdict[] = []\n): EntryIssue[][] {\n return rows.map((row, i) => {\n const issues: EntryIssue[] = []\n const name = 'name' in row.values ? text(row.values.name) : ''\n const controlNo = 'controlNo' in row.values ? text(row.values.controlNo) : ''\n const others = existing.filter(one => one.id !== row.id)\n\n if (name && others.some(one => text(one.name) === name))\n issues.push({ field: 'name', code: 'duplicate', messageKey: 'text.organization-entry-department-name-exists', blocking: true })\n if (controlNo && others.some(one => text(one.controlNo) === controlNo))\n issues.push({ field: 'controlNo', code: 'duplicate', messageKey: 'text.organization-entry-department-control-no-exists', blocking: true })\n\n const earlier = rows.slice(0, i).filter(other => other.id !== row.id)\n if ((name && earlier.some(other => text(other.values.name) === name)) || (controlNo && earlier.some(other => text(other.values.controlNo) === controlNo)))\n issues.push({ code: 'duplicate-in-proposal', messageKey: 'text.organization-entry-department-repeated', blocking: true })\n\n if (parents[i] === 'loop') issues.push({ field: 'parent', code: 'parent-loop', messageKey: 'text.organization-entry-department-parent-loop', blocking: true })\n if (parents[i] === 'not-found') issues.push({ field: 'parent', code: 'parent-not-found', messageKey: 'text.organization-entry-department-parent-not-found', blocking: true })\n\n return issues\n })\n}\n\n/** The id of a changed parent - `{ id }` when the reference was resolved; anything else is not asked about. */\nexport function changedParentId(values: Record<string, unknown>): string | undefined {\n const parent = values.parent\n return parent && typeof parent === 'object' && typeof (parent as any).id === 'string' ? (parent as any).id : undefined\n}\n\n/** checkedParent's refusal as a verdict - any other error (the database, say) is not a verdict and is passed on. */\nexport function parentVerdictOf(error: unknown): ParentVerdict {\n const code = (error as any)?.code\n if (code === 'department-parent-loop') return 'loop'\n if (code === 'department-parent-not-found') return 'not-found'\n return undefined\n}\n"]}
@@ -60,15 +60,16 @@ function getModelValue(patch) {
60
60
  };
61
61
  })
62
62
  .filter(m => m.type)
63
- .filter(m => {
63
+ .map((m, index) => {
64
+ /* A step that names its person - an employee, a department, a role - and names none is refused, not dropped. */
64
65
  switch (m.type) {
65
66
  case approval_line_item_1.OrgMemberTargetType.Employee:
66
67
  case approval_line_item_1.OrgMemberTargetType.Department:
67
68
  case approval_line_item_1.OrgMemberTargetType.Role:
68
- return !!m.approver?.id;
69
- default:
70
- return true;
69
+ if (!m.approver?.id)
70
+ throw new shell_1.Refusal('approval-line-approver-required', { row: index + 1 }, `row ${index + 1}: choose the approver`);
71
71
  }
72
+ return m;
72
73
  });
73
74
  }
74
75
  let ApprovalLineMutation = class ApprovalLineMutation {
@@ -377,6 +378,7 @@ tslib_1.__decorate([
377
378
  tslib_1.__metadata("design:returntype", Promise)
378
379
  ], ApprovalLineMutation.prototype, "importApprovalLines", null);
379
380
  exports.ApprovalLineMutation = ApprovalLineMutation = tslib_1.__decorate([
380
- (0, type_graphql_1.Resolver)(approval_line_1.ApprovalLine)
381
+ (0, type_graphql_1.Resolver)(approval_line_1.ApprovalLine),
382
+ (0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
381
383
  ], ApprovalLineMutation);
382
384
  //# sourceMappingURL=approval-line-mutation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"approval-line-mutation.js","sourceRoot":"","sources":["../../../server/service/approval-line/approval-line-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { requireMyEmployee } from '../employee/my-employee.js'\nimport { In } from 'typeorm'\n\nimport { getRepository } from '@things-factory/shell'\nimport { Employee } from '../employee/employee'\nimport { ApprovalLine, ApprovalLineOwnerType } from './approval-line'\nimport { ApprovalLineItem, OrgMemberTargetType } from './approval-line-item'\nimport { NewApprovalLine, ApprovalLinePatch } from './approval-line-type'\n\nasync function getOwnerValue(\n approvalLine: ApprovalLine | NewApprovalLine | ApprovalLinePatch,\n patch: NewApprovalLine | ApprovalLinePatch,\n context: ResolverContext\n) {\n if (!('owner' in patch || 'ownerType' in patch)) {\n /* owner 또는 ownerType 하나도 언급되지 않았다면, 업데이트하지 않는다. */\n return\n }\n\n const { domain, tx } = context.state\n const { ownerType, owner } = patch\n\n if (!ownerType || !owner) {\n /* ownerType이 클리어되거나, owner가 지정되지 않았다면, 클리어시킨다. */\n return null\n }\n\n var ownerObject\n\n switch (ownerType || approvalLine.ownerType) {\n case ApprovalLineOwnerType.Employee:\n ownerObject = await getRepository(Employee, tx).findOneBy({ domain: { id: domain.id }, id: owner.id })\n break\n default:\n }\n\n return ownerObject?.id || null\n}\n\nfunction getModelValue(patch: NewApprovalLine | ApprovalLinePatch): ApprovalLineItem[] {\n if (!('model' in patch)) {\n /* model이 언급되지 않았다면, 업데이트하지 않는다. */\n return\n }\n\n const { model } = patch\n\n if (!model || !(model instanceof Array)) {\n /* model의 값이 없거나 배열이 아니라면, 클리어시킨다. */\n return null\n }\n\n return model\n .map(m => {\n /*\n * ── 칸을 하나씩 옮겨 적는 자리다. 새 칸을 여기 안 적으면 조용히 사라진다 ──────────\n * `participation` 과 `notifyAfter` 가 이 목록에 없어서, 편집기에서 「참조」로 고쳐도 저장되지\n * 않았다. 오류도 나지 않는다 — 화면에서는 고쳐지고, 다시 읽으면 결재자로 돌아온다.\n *\n * 두 칸은 `ApprovalLineItem` 에 선언되어 있다(`approval-line-item.ts`). 선언은 있고 쓰는 길이\n * 없던 것이다.\n *\n * `ApprovalLineItem` 에 칸을 더하면 **여기도 함께 고쳐야 한다.**\n */\n return {\n type: m.type,\n approver: m.approver,\n participation: m.participation,\n notifyAfter: m.notifyAfter\n } as ApprovalLineItem\n })\n .filter(m => m.type)\n .filter(m => {\n switch (m.type) {\n case OrgMemberTargetType.Employee:\n case OrgMemberTargetType.Department:\n case OrgMemberTargetType.Role:\n return !!m.approver?.id\n default:\n return true\n }\n })\n}\n\n@Resolver(ApprovalLine)\nexport class ApprovalLineMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ApprovalLine, { description: 'To create new ApprovalLine' })\n async createApprovalLine(\n @Arg('approvalLine') approvalLine: NewApprovalLine,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n\n const result = await getRepository(ApprovalLine, tx).save({\n ...approvalLine,\n ownerValue: await getOwnerValue(approvalLine, approvalLine, context),\n model: getModelValue(approvalLine),\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Mutation(returns => ApprovalLine, { description: 'To create new ApprovalLine for current user' })\n async createMyApprovalLine(\n @Arg('approvalLine') approvalLine: NewApprovalLine,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n const employee = await requireMyEmployee(context)\n\n const result = await getRepository(ApprovalLine, tx).save({\n ...approvalLine,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(approvalLine),\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ApprovalLine, { description: 'To modify ApprovalLine information' })\n async updateApprovalLine(\n @Arg('id') id: string,\n @Arg('patch') patch: ApprovalLinePatch,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(ApprovalLine, tx)\n const approvalLine = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const result = await repository.save({\n ...approvalLine,\n ...patch,\n ownerValue: await getOwnerValue(approvalLine, patch, context),\n model: getModelValue(patch),\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Mutation(returns => ApprovalLine, { description: 'To modify ApprovalLine information for current user' })\n async updateMyApprovalLine(\n @Arg('id') id: string,\n @Arg('patch') patch: ApprovalLinePatch,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n /*\n * **검사가 여기 없었다.** 사원 기록이 없으면 아래 `employee.id` 에서 null 참조로 터졌고, 그\n * 문장은 옆의 넷이 던지던 것보다 알아보기 어려웠다. 넷은 검사하고 하나는 안 하는 상태가 더 나쁜\n * 이유는, 고친 사람이 「검사가 있다」고 믿게 되기 때문이다.\n */\n const employee = await requireMyEmployee(context)\n\n const repository = getRepository(ApprovalLine, tx)\n const approvalLine = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const result = await repository.save({\n ...approvalLine,\n ...patch,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(patch),\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [ApprovalLine], { description: \"To modify multiple ApprovalLines' information\" })\n async updateMultipleApprovalLine(\n @Arg('patches', type => [ApprovalLinePatch]) patches: ApprovalLinePatch[],\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const approvalLineRepo = getRepository(ApprovalLine, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await approvalLineRepo.save({\n ...newRecord,\n ownerValue: await getOwnerValue(newRecord, newRecord, context),\n model: getModelValue(newRecord),\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const approvalLine = await approvalLineRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!approvalLine) {\n throw new Error(`failed to find approvalLine to update: ${updateRecord.id}`)\n }\n\n const result = await approvalLineRepo.save({\n ...approvalLine,\n ...updateRecord,\n ownerValue: await getOwnerValue(approvalLine, updateRecord, context),\n model: getModelValue(updateRecord),\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Mutation(returns => [ApprovalLine], {\n description: \"To modify multiple ApprovalLines' information for current user\"\n })\n async updateMultipleMyApprovalLine(\n @Arg('patches', type => [ApprovalLinePatch]) patches: ApprovalLinePatch[],\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine[]> {\n const { domain, user, tx } = context.state\n\n const employee = await requireMyEmployee(context)\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const approvalLineRepo = getRepository(ApprovalLine, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await approvalLineRepo.save({\n ...newRecord,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(newRecord),\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const approvalLine = await approvalLineRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!approvalLine) {\n throw new Error(`failed to find approvalLine to update: ${updateRecord.id}`)\n }\n\n const result = await approvalLineRepo.save({\n ...approvalLine,\n ...updateRecord,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(updateRecord),\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete ApprovalLine' })\n async deleteApprovalLine(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(ApprovalLine, tx).delete({ domain: { id: domain.id }, id })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple ApprovalLines' })\n async deleteApprovalLines(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(ApprovalLine, tx).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete ApprovalLine for current user' })\n async deleteMyApprovalLine(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, user, tx } = context.state\n\n const employee = await requireMyEmployee(context)\n\n await getRepository(ApprovalLine, tx).delete({\n id,\n domain: { id: domain.id },\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete multiple ApprovalLines for current user' })\n async deleteMyApprovalLines(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, user, tx } = context.state\n\n const employee = await requireMyEmployee(context)\n\n await getRepository(ApprovalLine, tx).delete({\n domain: { id: domain.id },\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import multiple ApprovalLines' })\n async importApprovalLines(\n @Arg('approvalLines', type => [ApprovalLinePatch]) approvalLines: ApprovalLinePatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await Promise.all(\n approvalLines.map(async (approvalLine: ApprovalLinePatch) => {\n const createdApprovalLine: ApprovalLine = await getRepository(ApprovalLine, tx).save({\n domain,\n ...approvalLine\n })\n })\n )\n\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"approval-line-mutation.js","sourceRoot":"","sources":["../../../server/service/approval-line/approval-line-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive, UseMiddleware } from 'type-graphql'\nimport { requireMyEmployee } from '../employee/my-employee.js'\nimport { In } from 'typeorm'\n\nimport { getRepository, Refusal, SpeakRefusals } from '@things-factory/shell'\nimport { Employee } from '../employee/employee'\nimport { ApprovalLine, ApprovalLineOwnerType } from './approval-line'\nimport { ApprovalLineItem, OrgMemberTargetType } from './approval-line-item'\nimport { NewApprovalLine, ApprovalLinePatch } from './approval-line-type'\n\nasync function getOwnerValue(\n approvalLine: ApprovalLine | NewApprovalLine | ApprovalLinePatch,\n patch: NewApprovalLine | ApprovalLinePatch,\n context: ResolverContext\n) {\n if (!('owner' in patch || 'ownerType' in patch)) {\n /* owner 또는 ownerType 하나도 언급되지 않았다면, 업데이트하지 않는다. */\n return\n }\n\n const { domain, tx } = context.state\n const { ownerType, owner } = patch\n\n if (!ownerType || !owner) {\n /* ownerType이 클리어되거나, owner가 지정되지 않았다면, 클리어시킨다. */\n return null\n }\n\n var ownerObject\n\n switch (ownerType || approvalLine.ownerType) {\n case ApprovalLineOwnerType.Employee:\n ownerObject = await getRepository(Employee, tx).findOneBy({ domain: { id: domain.id }, id: owner.id })\n break\n default:\n }\n\n return ownerObject?.id || null\n}\n\nfunction getModelValue(patch: NewApprovalLine | ApprovalLinePatch): ApprovalLineItem[] {\n if (!('model' in patch)) {\n /* model이 언급되지 않았다면, 업데이트하지 않는다. */\n return\n }\n\n const { model } = patch\n\n if (!model || !(model instanceof Array)) {\n /* model의 값이 없거나 배열이 아니라면, 클리어시킨다. */\n return null\n }\n\n return model\n .map(m => {\n /*\n * ── 칸을 하나씩 옮겨 적는 자리다. 새 칸을 여기 안 적으면 조용히 사라진다 ──────────\n * `participation` 과 `notifyAfter` 가 이 목록에 없어서, 편집기에서 「참조」로 고쳐도 저장되지\n * 않았다. 오류도 나지 않는다 — 화면에서는 고쳐지고, 다시 읽으면 결재자로 돌아온다.\n *\n * 두 칸은 `ApprovalLineItem` 에 선언되어 있다(`approval-line-item.ts`). 선언은 있고 쓰는 길이\n * 없던 것이다.\n *\n * `ApprovalLineItem` 에 칸을 더하면 **여기도 함께 고쳐야 한다.**\n */\n return {\n type: m.type,\n approver: m.approver,\n participation: m.participation,\n notifyAfter: m.notifyAfter\n } as ApprovalLineItem\n })\n .filter(m => m.type)\n .map((m, index) => {\n /* A step that names its person - an employee, a department, a role - and names none is refused, not dropped. */\n switch (m.type) {\n case OrgMemberTargetType.Employee:\n case OrgMemberTargetType.Department:\n case OrgMemberTargetType.Role:\n if (!m.approver?.id)\n throw new Refusal('approval-line-approver-required', { row: index + 1 }, `row ${index + 1}: choose the approver`)\n }\n return m\n })\n}\n\n@Resolver(ApprovalLine)\n@UseMiddleware(SpeakRefusals)\nexport class ApprovalLineMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ApprovalLine, { description: 'To create new ApprovalLine' })\n async createApprovalLine(\n @Arg('approvalLine') approvalLine: NewApprovalLine,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n\n const result = await getRepository(ApprovalLine, tx).save({\n ...approvalLine,\n ownerValue: await getOwnerValue(approvalLine, approvalLine, context),\n model: getModelValue(approvalLine),\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Mutation(returns => ApprovalLine, { description: 'To create new ApprovalLine for current user' })\n async createMyApprovalLine(\n @Arg('approvalLine') approvalLine: NewApprovalLine,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n const employee = await requireMyEmployee(context)\n\n const result = await getRepository(ApprovalLine, tx).save({\n ...approvalLine,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(approvalLine),\n domain,\n creator: user,\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => ApprovalLine, { description: 'To modify ApprovalLine information' })\n async updateApprovalLine(\n @Arg('id') id: string,\n @Arg('patch') patch: ApprovalLinePatch,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(ApprovalLine, tx)\n const approvalLine = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const result = await repository.save({\n ...approvalLine,\n ...patch,\n ownerValue: await getOwnerValue(approvalLine, patch, context),\n model: getModelValue(patch),\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Mutation(returns => ApprovalLine, { description: 'To modify ApprovalLine information for current user' })\n async updateMyApprovalLine(\n @Arg('id') id: string,\n @Arg('patch') patch: ApprovalLinePatch,\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine> {\n const { domain, user, tx } = context.state\n /*\n * **검사가 여기 없었다.** 사원 기록이 없으면 아래 `employee.id` 에서 null 참조로 터졌고, 그\n * 문장은 옆의 넷이 던지던 것보다 알아보기 어려웠다. 넷은 검사하고 하나는 안 하는 상태가 더 나쁜\n * 이유는, 고친 사람이 「검사가 있다」고 믿게 되기 때문이다.\n */\n const employee = await requireMyEmployee(context)\n\n const repository = getRepository(ApprovalLine, tx)\n const approvalLine = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const result = await repository.save({\n ...approvalLine,\n ...patch,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(patch),\n updater: user\n })\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [ApprovalLine], { description: \"To modify multiple ApprovalLines' information\" })\n async updateMultipleApprovalLine(\n @Arg('patches', type => [ApprovalLinePatch]) patches: ApprovalLinePatch[],\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const approvalLineRepo = getRepository(ApprovalLine, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await approvalLineRepo.save({\n ...newRecord,\n ownerValue: await getOwnerValue(newRecord, newRecord, context),\n model: getModelValue(newRecord),\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const approvalLine = await approvalLineRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!approvalLine) {\n throw new Error(`failed to find approvalLine to update: ${updateRecord.id}`)\n }\n\n const result = await approvalLineRepo.save({\n ...approvalLine,\n ...updateRecord,\n ownerValue: await getOwnerValue(approvalLine, updateRecord, context),\n model: getModelValue(updateRecord),\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Mutation(returns => [ApprovalLine], {\n description: \"To modify multiple ApprovalLines' information for current user\"\n })\n async updateMultipleMyApprovalLine(\n @Arg('patches', type => [ApprovalLinePatch]) patches: ApprovalLinePatch[],\n @Ctx() context: ResolverContext\n ): Promise<ApprovalLine[]> {\n const { domain, user, tx } = context.state\n\n const employee = await requireMyEmployee(context)\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const approvalLineRepo = getRepository(ApprovalLine, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n\n const result = await approvalLineRepo.save({\n ...newRecord,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(newRecord),\n domain,\n creator: user,\n updater: user\n })\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const approvalLine = await approvalLineRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!approvalLine) {\n throw new Error(`failed to find approvalLine to update: ${updateRecord.id}`)\n }\n\n const result = await approvalLineRepo.save({\n ...approvalLine,\n ...updateRecord,\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n model: getModelValue(updateRecord),\n updater: user\n })\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete ApprovalLine' })\n async deleteApprovalLine(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(ApprovalLine, tx).delete({ domain: { id: domain.id }, id })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple ApprovalLines' })\n async deleteApprovalLines(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(ApprovalLine, tx).delete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete ApprovalLine for current user' })\n async deleteMyApprovalLine(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, user, tx } = context.state\n\n const employee = await requireMyEmployee(context)\n\n await getRepository(ApprovalLine, tx).delete({\n id,\n domain: { id: domain.id },\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Mutation(returns => Boolean, { description: 'To delete multiple ApprovalLines for current user' })\n async deleteMyApprovalLines(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, user, tx } = context.state\n\n const employee = await requireMyEmployee(context)\n\n await getRepository(ApprovalLine, tx).delete({\n domain: { id: domain.id },\n ownerType: ApprovalLineOwnerType.Employee,\n ownerValue: employee.id,\n id: In(ids)\n })\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"organization\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import multiple ApprovalLines' })\n async importApprovalLines(\n @Arg('approvalLines', type => [ApprovalLinePatch]) approvalLines: ApprovalLinePatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await Promise.all(\n approvalLines.map(async (approvalLine: ApprovalLinePatch) => {\n const createdApprovalLine: ApprovalLine = await getRepository(ApprovalLine, tx).save({\n domain,\n ...approvalLine\n })\n })\n )\n\n return true\n }\n}\n"]}
@@ -214,6 +214,7 @@ tslib_1.__decorate([
214
214
  tslib_1.__metadata("design:returntype", Promise)
215
215
  ], DepartmentMutation.prototype, "importDepartments", null);
216
216
  exports.DepartmentMutation = DepartmentMutation = tslib_1.__decorate([
217
- (0, type_graphql_1.Resolver)(department_1.Department)
217
+ (0, type_graphql_1.Resolver)(department_1.Department),
218
+ (0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
218
219
  ], DepartmentMutation);
219
220
  //# sourceMappingURL=department-mutation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"department-mutation.js","sourceRoot":"","sources":["../../../server/service/department/department-mutation.ts"],"names":[],"mappings":";;;;AAAA,+CAAsE;AACtE,qCAA4B;AAE5B,iDAAqD;AACrD,qEAA0F;AAE1F,6CAAyC;AACzC,uDAAkE;AAClE,mDAA+C;AAC/C,2DAAmD;AACnD,0DAAuD;AAGhD,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAIvB,AAAN,KAAK,CAAC,gBAAgB,CACD,UAAyB,EACrC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE1C,MAAM,OAAO,GAAG,MAAM,IAAA,oCAAiB,EACrC,IAAA,qBAAa,EAAC,mBAAQ,EAAE,EAAE,CAAC,EAC3B,SAAS,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EACxD,MAAM,EACN,SAAS,CACV,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAa,EAAC,SAAS,EAAE,UAAU,EAAE,IAAA,qBAAa,EAAC,uBAAU,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,CAAA;QAEhG,MAAM,MAAM,GAAG,MAAM,IAAA,qBAAa,EAAC,uBAAU,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC;YACtD,GAAG,UAAU;YACb,MAAM;YACN,MAAM;YACN,OAAO;YACP,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,IAAI;SACd,CAAC,CAAA;QAEF,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,IAAA,kCAAgB,EACpB,IAAI,EACJ;gBACE,UAAU,EAAE;oBACV,IAAI,EAAE,UAAU,CAAC,OAAO;oBACxB,OAAO,EAAE,uBAAU,CAAC,IAAI;oBACxB,KAAK,EAAE,MAAM,CAAC,EAAE;iBACjB;aACF,EACD,OAAO,CACR,CAAA;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAKK,AAAN,KAAK,CAAC,gBAAgB,CACT,EAAU,EACP,KAAsB,EAC7B,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE1C,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,uBAAU,EAAE,EAAE,CAAC,CAAA;QAChD,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;YAC1C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;SACzC,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,MAAM,IAAA,oCAAiB,EACrC,IAAA,qBAAa,EAAC,mBAAQ,EAAE,EAAE,CAAC,EAC3B,SAAS,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAC9C,MAAM,EACN,SAAS,CACV,CAAA;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAa,EAAC,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;QAEjE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC;YACnC,GAAG,UAAU;YACb,GAAG,KAAK;YACR,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC;YACvC,OAAO;YACP,OAAO,EAAE,IAAI;SACd,CAAC,CAAA;QAEF,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAA,wCAAsB,EAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;YACpE,MAAM,IAAA,kCAAgB,EACpB,IAAI,EACJ;gBACE,UAAU,EAAE;oBACV,IAAI,EAAE,KAAK,CAAC,OAAO;oBACnB,OAAO,EAAE,uBAAU,CAAC,IAAI;oBACxB,KAAK,EAAE,MAAM,CAAC,EAAE;iBACjB;aACF,EACD,OAAO,CACR,CAAA;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAKK,AAAN,KAAK,CAAC,wBAAwB,CACe,OAA0B,EAC9D,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAE1C,IAAI,OAAO,GAAG,EAAE,CAAA;QAChB,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAA;QACzF,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAA;QACzF,MAAM,cAAc,GAAG,IAAA,qBAAa,EAAC,uBAAU,EAAE,EAAE,CAAC,CAAA;QAEpD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;gBACnC,MAAM,OAAO,GAAG,MAAM,IAAA,oCAAiB,EACrC,IAAA,qBAAa,EAAC,mBAAQ,EAAE,EAAE,CAAC,EAC3B,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EACtD,MAAM,EACN,SAAS,CACV,CAAA;gBAED,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAa,EAAC,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,CAAC,CAAA;gBAEhF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC;oBACvC,GAAG,SAAS;oBACZ,MAAM;oBACN,OAAO;oBACP,MAAM;oBACN,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,IAAI;iBACd,CAAC,CAAA;gBAEF,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;oBACtB,MAAM,IAAA,kCAAgB,EACpB,IAAI,EACJ;wBACE,UAAU,EAAE;4BACV,IAAI,EAAE,SAAS,CAAC,OAAO;4BACvB,OAAO,EAAE,uBAAU,CAAC,IAAI;4BACxB,KAAK,EAAE,MAAM,CAAC,EAAE;yBACjB;qBACF,EACD,OAAO,CACR,CAAA;gBACH,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;gBACtC,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC;oBAC9C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE;iBAC1D,CAAC,CAAA;gBAEF,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,MAAM,IAAI,KAAK,CAAC,wCAAwC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAA;gBAC5E,CAAC;gBACD,MAAM,OAAO,GAAG,MAAM,IAAA,oCAAiB,EACrC,IAAA,qBAAa,EAAC,mBAAQ,EAAE,EAAE,CAAC,EAC3B,SAAS,IAAI,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAC5D,MAAM,EACN,SAAS,CACV,CAAA;gBAED,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAa,EAAC,UAAU,CAAC,EAAE,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,CAAC,CAAA;gBAEvF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC;oBACvC,GAAG,UAAU;oBACb,GAAG,YAAY;oBACf,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,CAAC;oBACvC,OAAO;oBACP,OAAO,EAAE,IAAI;iBACd,CAAC,CAAA;gBAEF,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;oBACzB,MAAM,IAAA,wCAAsB,EAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;oBACpE,MAAM,IAAA,kCAAgB,EACpB,IAAI,EACJ;wBACE,UAAU,EAAE;4BACV,IAAI,EAAE,YAAY,CAAC,OAAO;4BAC1B,OAAO,EAAE,uBAAU,CAAC,IAAI;4BACxB,KAAK,EAAE,MAAM,CAAC,EAAE;yBACjB;qBACF,EACD,OAAO,CACR,CAAA;gBACH,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAKK,AAAN,KAAK,CAAC,gBAAgB,CAAY,EAAU,EAAS,OAAwB;QAC3E,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEpC,MAAM,IAAA,qBAAa,EAAC,uBAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QACjF,gEAAgE;QAEhE,OAAO,IAAI,CAAA;IACb,CAAC;IAKK,AAAN,KAAK,CAAC,iBAAiB,CACS,GAAa,EACpC,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEpC,MAAM,IAAA,qBAAa,EAAC,uBAAU,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC;YAC7C,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;YACzB,EAAE,EAAE,IAAA,YAAE,EAAC,GAAG,CAAC;SACZ,CAAC,CAAA;QAEF,+DAA+D;QAE/D,OAAO,IAAI,CAAA;IACb,CAAC;IAKK,AAAN,KAAK,CAAC,iBAAiB,CAC0B,WAA8B,EACtE,OAAwB;QAE/B,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAEpC,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,uBAAU,EAAE,EAAE,CAAC,CAAA;QAEhD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAa,EAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,CAAA;YAC7E,MAAM,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;QAC1D,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;CACF,CAAA;AAtPY,gDAAkB;AAIvB;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,qFAAqF,CAAC;IAChG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,uBAAU,EAAE,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;IAE1E,mBAAA,IAAA,kBAAG,EAAC,YAAY,CAAC,CAAA;IACjB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CADyB,+BAAa;;0DAsC7C;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,qFAAqF,CAAC;IAChG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,uBAAU,EAAE,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;IAElF,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IACT,mBAAA,IAAA,kBAAG,EAAC,OAAO,CAAC,CAAA;IACZ,mBAAA,IAAA,kBAAG,GAAE,CAAA;;qDADe,iCAAe;;0DA2CrC;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,qFAAqF,CAAC;IAChG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,uBAAU,CAAC,EAAE,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;IAE/F,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,iCAAe,CAAC,CAAC,CAAA;IACzC,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;kEA+FP;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,qFAAqF,CAAC;IAChG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;IAC9C,mBAAA,IAAA,kBAAG,EAAC,IAAI,CAAC,CAAA;IAAc,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;0DAOnD;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,qFAAqF,CAAC;IAChG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;IAE7E,mBAAA,IAAA,kBAAG,EAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;2DAYP;AAKK;IAHL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,qFAAqF,CAAC;IAChG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;IAE7E,mBAAA,IAAA,kBAAG,EAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,iCAAe,CAAC,CAAC,CAAA;IAC7C,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;2DAYP;6BArPU,kBAAkB;IAD9B,IAAA,uBAAQ,EAAC,uBAAU,CAAC;GACR,kBAAkB,CAsP9B","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport { getRepository } from '@things-factory/shell'\nimport { createAttachment, deleteAttachmentsByRef } from '@things-factory/attachment-base'\n\nimport { Department } from './department'\nimport { NewDepartment, DepartmentPatch } from './department-type'\nimport { Employee } from '../employee/employee'\nimport { checkedParent } from './department-parent'\nimport { referenceInDomain } from '../domain-reference'\n\n@Resolver(Department)\nexport class DepartmentMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Department, { description: 'To create new Department' })\n async createDepartment(\n @Arg('department') department: NewDepartment,\n @Ctx() context: ResolverContext\n ): Promise<Department> {\n const { domain, user, tx } = context.state\n\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in department ? department.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(undefined, department, getRepository(Department, tx), domain)\n\n const result = await getRepository(Department, tx).save({\n ...department,\n parent,\n domain,\n manager,\n creator: user,\n updater: user\n })\n\n if (department.picture) {\n await createAttachment(\n null,\n {\n attachment: {\n file: department.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Department, { description: 'To modify Department information' })\n async updateDepartment(\n @Arg('id') id: string,\n @Arg('patch') patch: DepartmentPatch,\n @Ctx() context: ResolverContext\n ): Promise<Department> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(Department, tx)\n const department = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in patch ? patch.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(id, patch, repository, domain)\n\n const result = await repository.save({\n ...department,\n ...patch,\n ...(parent !== undefined && { parent }),\n manager,\n updater: user\n })\n\n if (patch.picture) {\n await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)\n await createAttachment(\n null,\n {\n attachment: {\n file: patch.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Department], { description: \"To modify multiple Departments' information\" })\n async updateMultipleDepartment(\n @Arg('patches', type => [DepartmentPatch]) patches: DepartmentPatch[],\n @Ctx() context: ResolverContext\n ): Promise<Department[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const departmentRepo = getRepository(Department, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in newRecord ? newRecord.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(undefined, newRecord, departmentRepo, domain)\n\n const result = await departmentRepo.save({\n ...newRecord,\n parent,\n manager,\n domain,\n creator: user,\n updater: user\n })\n\n if (newRecord.picture) {\n await createAttachment(\n null,\n {\n attachment: {\n file: newRecord.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const department = await departmentRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!department) {\n throw new Error(`failed to find department to update: ${updateRecord.id}`)\n }\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in updateRecord ? updateRecord.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(department.id, updateRecord, departmentRepo, domain)\n\n const result = await departmentRepo.save({\n ...department,\n ...updateRecord,\n ...(parent !== undefined && { parent }),\n manager,\n updater: user\n })\n\n if (updateRecord.picture) {\n await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)\n await createAttachment(\n null,\n {\n attachment: {\n file: updateRecord.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete Department' })\n async deleteDepartment(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(Department, tx).softDelete({ domain: { id: domain.id }, id })\n // await deleteAttachmentsByRef(null, { refBys: [id] }, context)\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple Departments' })\n async deleteDepartments(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(Department, tx).softDelete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n // await deleteAttachmentsByRef(null, { refBys: ids }, context)\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import multiple Departments' })\n async importDepartments(\n @Arg('departments', type => [DepartmentPatch]) departments: DepartmentPatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n const repository = getRepository(Department, tx)\n\n for (const department of departments) {\n const parent = await checkedParent(undefined, department, repository, domain)\n await repository.save({ domain, ...department, parent })\n }\n\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"department-mutation.js","sourceRoot":"","sources":["../../../server/service/department/department-mutation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Mutation, Arg, Ctx, Directive, UseMiddleware } from 'type-graphql'\nimport { In } from 'typeorm'\n\nimport { getRepository, SpeakRefusals } from '@things-factory/shell'\nimport { createAttachment, deleteAttachmentsByRef } from '@things-factory/attachment-base'\n\nimport { Department } from './department'\nimport { NewDepartment, DepartmentPatch } from './department-type'\nimport { Employee } from '../employee/employee'\nimport { checkedParent } from './department-parent'\nimport { referenceInDomain } from '../domain-reference'\n\n@Resolver(Department)\n@UseMiddleware(SpeakRefusals)\nexport class DepartmentMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Department, { description: 'To create new Department' })\n async createDepartment(\n @Arg('department') department: NewDepartment,\n @Ctx() context: ResolverContext\n ): Promise<Department> {\n const { domain, user, tx } = context.state\n\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in department ? department.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(undefined, department, getRepository(Department, tx), domain)\n\n const result = await getRepository(Department, tx).save({\n ...department,\n parent,\n domain,\n manager,\n creator: user,\n updater: user\n })\n\n if (department.picture) {\n await createAttachment(\n null,\n {\n attachment: {\n file: department.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Department, { description: 'To modify Department information' })\n async updateDepartment(\n @Arg('id') id: string,\n @Arg('patch') patch: DepartmentPatch,\n @Ctx() context: ResolverContext\n ): Promise<Department> {\n const { domain, user, tx } = context.state\n\n const repository = getRepository(Department, tx)\n const department = await repository.findOne({\n where: { domain: { id: domain.id }, id }\n })\n\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in patch ? patch.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(id, patch, repository, domain)\n\n const result = await repository.save({\n ...department,\n ...patch,\n ...(parent !== undefined && { parent }),\n manager,\n updater: user\n })\n\n if (patch.picture) {\n await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)\n await createAttachment(\n null,\n {\n attachment: {\n file: patch.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n return result\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => [Department], { description: \"To modify multiple Departments' information\" })\n async updateMultipleDepartment(\n @Arg('patches', type => [DepartmentPatch]) patches: DepartmentPatch[],\n @Ctx() context: ResolverContext\n ): Promise<Department[]> {\n const { domain, user, tx } = context.state\n\n let results = []\n const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')\n const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')\n const departmentRepo = getRepository(Department, tx)\n\n if (_createRecords.length > 0) {\n for (let i = 0; i < _createRecords.length; i++) {\n const newRecord = _createRecords[i]\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in newRecord ? newRecord.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(undefined, newRecord, departmentRepo, domain)\n\n const result = await departmentRepo.save({\n ...newRecord,\n parent,\n manager,\n domain,\n creator: user,\n updater: user\n })\n\n if (newRecord.picture) {\n await createAttachment(\n null,\n {\n attachment: {\n file: newRecord.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n results.push({ ...result, cuFlag: '+' })\n }\n }\n\n if (_updateRecords.length > 0) {\n for (let i = 0; i < _updateRecords.length; i++) {\n const updateRecord = _updateRecords[i]\n const department = await departmentRepo.findOne({\n where: { domain: { id: domain.id }, id: updateRecord.id }\n })\n\n if (!department) {\n throw new Error(`failed to find department to update: ${updateRecord.id}`)\n }\n const manager = await referenceInDomain(\n getRepository(Employee, tx),\n 'manager' in updateRecord ? updateRecord.manager : undefined,\n domain,\n 'manager'\n )\n\n const parent = await checkedParent(department.id, updateRecord, departmentRepo, domain)\n\n const result = await departmentRepo.save({\n ...department,\n ...updateRecord,\n ...(parent !== undefined && { parent }),\n manager,\n updater: user\n })\n\n if (updateRecord.picture) {\n await deleteAttachmentsByRef(null, { refBys: [result.id] }, context)\n await createAttachment(\n null,\n {\n attachment: {\n file: updateRecord.picture,\n refType: Department.name,\n refBy: result.id\n }\n },\n context\n )\n }\n\n results.push({ ...result, cuFlag: 'M' })\n }\n }\n\n return results\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete Department' })\n async deleteDepartment(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(Department, tx).softDelete({ domain: { id: domain.id }, id })\n // await deleteAttachmentsByRef(null, { refBys: [id] }, context)\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To delete multiple Departments' })\n async deleteDepartments(\n @Arg('ids', type => [String]) ids: string[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n await getRepository(Department, tx).softDelete({\n domain: { id: domain.id },\n id: In(ids)\n })\n\n // await deleteAttachmentsByRef(null, { refBys: ids }, context)\n\n return true\n }\n\n @Directive('@transaction')\n @Directive('@privilege(category: \"department\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => Boolean, { description: 'To import multiple Departments' })\n async importDepartments(\n @Arg('departments', type => [DepartmentPatch]) departments: DepartmentPatch[],\n @Ctx() context: ResolverContext\n ): Promise<boolean> {\n const { domain, tx } = context.state\n\n const repository = getRepository(Department, tx)\n\n for (const department of departments) {\n const parent = await checkedParent(undefined, department, repository, domain)\n await repository.save({ domain, ...department, parent })\n }\n\n return true\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkedParent = checkedParent;
4
+ const shell_1 = require("@things-factory/shell");
4
5
  /*
5
6
  * The parent a patch asks for, checked before it is saved.
6
7
  *
@@ -20,11 +21,11 @@ async function checkedParent(departmentId, patch, repository, domain) {
20
21
  const parentId = patch.parent.id;
21
22
  let ancestor = await repository.findOne({ where: { domain: { id: domain.id }, id: parentId } });
22
23
  if (!ancestor) {
23
- throw new Error(`parent department not found: ${parentId}`);
24
+ throw new shell_1.Refusal('department-parent-not-found', {}, `parent department not found: ${parentId}`);
24
25
  }
25
26
  while (ancestor) {
26
27
  if (departmentId && ancestor.id === departmentId) {
27
- throw new Error(`a department cannot be placed under itself or under one of its own sub-departments: ${parentId}`);
28
+ throw new shell_1.Refusal('department-parent-loop', {}, `a department cannot be placed under itself or under one of its own sub-departments: ${parentId}`);
28
29
  }
29
30
  ancestor = ancestor.parentId
30
31
  ? await repository.findOne({ where: { domain: { id: domain.id }, id: ancestor.parentId } })
@@ -1 +1 @@
1
- {"version":3,"file":"department-parent.js","sourceRoot":"","sources":["../../../server/service/department/department-parent.ts"],"names":[],"mappings":";;AAiBA,sCA2BC;AAtCD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,aAAa,CACjC,YAAgC,EAChC,KAA0C,EAC1C,UAAkC,EAClC,MAAc;IAEd,IAAI,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxE,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAE1D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;IAChC,IAAI,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IAE/F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,EAAE,CAAC,CAAA;IAC7D,CAAC;IAED,OAAO,QAAQ,EAAE,CAAC;QAChB,IAAI,YAAY,IAAI,QAAQ,CAAC,EAAE,KAAK,YAAY,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,uFAAuF,QAAQ,EAAE,CAAC,CAAA;QACpH,CAAC;QAED,QAAQ,GAAG,QAAQ,CAAC,QAAQ;YAC1B,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC3F,CAAC,CAAC,IAAI,CAAA;IACV,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAA;AACzB,CAAC","sourcesContent":["import { Repository } from 'typeorm'\n\nimport { Domain } from '@things-factory/shell'\n\nimport { Department } from './department'\n\n/*\n * The parent a patch asks for, checked before it is saved.\n *\n * A department is refused as its own parent, and so is any department under it: the hierarchy would\n * loop, and every screen that walks it (the department list, the selector, the employee rail) would\n * lose that branch. The walk goes up from the requested parent, so it reads as many rows as the\n * organization is deep.\n *\n * 'parent' absent from the patch leaves the parent as it is (undefined); null makes the department\n * top-level.\n */\nexport async function checkedParent(\n departmentId: string | undefined,\n patch: { parent?: { id?: string } | null },\n repository: Repository<Department>,\n domain: Domain\n): Promise<{ id: string } | null | undefined> {\n if (!('parent' in patch) || patch.parent === undefined) return undefined\n if (patch.parent === null || !patch.parent.id) return null\n\n const parentId = patch.parent.id\n let ancestor = await repository.findOne({ where: { domain: { id: domain.id }, id: parentId } })\n\n if (!ancestor) {\n throw new Error(`parent department not found: ${parentId}`)\n }\n\n while (ancestor) {\n if (departmentId && ancestor.id === departmentId) {\n throw new Error(`a department cannot be placed under itself or under one of its own sub-departments: ${parentId}`)\n }\n\n ancestor = ancestor.parentId\n ? await repository.findOne({ where: { domain: { id: domain.id }, id: ancestor.parentId } })\n : null\n }\n\n return { id: parentId }\n}\n"]}
1
+ {"version":3,"file":"department-parent.js","sourceRoot":"","sources":["../../../server/service/department/department-parent.ts"],"names":[],"mappings":";;AAiBA,sCA2BC;AA1CD,iDAAuD;AAIvD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,aAAa,CACjC,YAAgC,EAChC,KAA0C,EAC1C,UAAkC,EAClC,MAAc;IAEd,IAAI,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACxE,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAE1D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAA;IAChC,IAAI,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IAE/F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,eAAO,CAAC,6BAA6B,EAAE,EAAE,EAAE,gCAAgC,QAAQ,EAAE,CAAC,CAAA;IAClG,CAAC;IAED,OAAO,QAAQ,EAAE,CAAC;QAChB,IAAI,YAAY,IAAI,QAAQ,CAAC,EAAE,KAAK,YAAY,EAAE,CAAC;YACjD,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,uFAAuF,QAAQ,EAAE,CAAC,CAAA;QACpJ,CAAC;QAED,QAAQ,GAAG,QAAQ,CAAC,QAAQ;YAC1B,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC3F,CAAC,CAAC,IAAI,CAAA;IACV,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAA;AACzB,CAAC","sourcesContent":["import { Repository } from 'typeorm'\n\nimport { Domain, Refusal } from '@things-factory/shell'\n\nimport { Department } from './department'\n\n/*\n * The parent a patch asks for, checked before it is saved.\n *\n * A department is refused as its own parent, and so is any department under it: the hierarchy would\n * loop, and every screen that walks it (the department list, the selector, the employee rail) would\n * lose that branch. The walk goes up from the requested parent, so it reads as many rows as the\n * organization is deep.\n *\n * 'parent' absent from the patch leaves the parent as it is (undefined); null makes the department\n * top-level.\n */\nexport async function checkedParent(\n departmentId: string | undefined,\n patch: { parent?: { id?: string } | null },\n repository: Repository<Department>,\n domain: Domain\n): Promise<{ id: string } | null | undefined> {\n if (!('parent' in patch) || patch.parent === undefined) return undefined\n if (patch.parent === null || !patch.parent.id) return null\n\n const parentId = patch.parent.id\n let ancestor = await repository.findOne({ where: { domain: { id: domain.id }, id: parentId } })\n\n if (!ancestor) {\n throw new Refusal('department-parent-not-found', {}, `parent department not found: ${parentId}`)\n }\n\n while (ancestor) {\n if (departmentId && ancestor.id === departmentId) {\n throw new Refusal('department-parent-loop', {}, `a department cannot be placed under itself or under one of its own sub-departments: ${parentId}`)\n }\n\n ancestor = ancestor.parentId\n ? await repository.findOne({ where: { domain: { id: domain.id }, id: ancestor.parentId } })\n : null\n }\n\n return { id: parentId }\n}\n"]}
@@ -3,7 +3,7 @@ import { Domain } from '@things-factory/shell';
3
3
  import { User } from '@things-factory/auth-base';
4
4
  export declare function referenceInDomain<T extends ObjectLiteral>(repository: Repository<T>, ref: {
5
5
  id?: string;
6
- } | null | undefined, domain: Domain, what: string): Promise<T | null | undefined>;
6
+ } | null | undefined, domain: Domain, what: 'manager' | 'supervisor' | 'department'): Promise<T | null | undefined>;
7
7
  export declare function userInDomain(ref: {
8
8
  id?: string;
9
9
  } | null | undefined, domain: Domain, tx?: EntityManager): Promise<User | null | undefined>;
@@ -22,7 +22,7 @@ async function referenceInDomain(repository, ref, domain, what) {
22
22
  return null;
23
23
  const found = await repository.findOne({ where: { domain: { id: domain.id }, id: ref.id } });
24
24
  if (!found) {
25
- throw new Error(`${what} not found in this domain: ${ref.id}`);
25
+ throw new shell_1.Refusal(`${what}-not-in-domain`, {}, `${what} not found in this domain: ${ref.id}`);
26
26
  }
27
27
  return found;
28
28
  }
@@ -41,7 +41,7 @@ async function userInDomain(ref, domain, tx) {
41
41
  .where('user.id = :id', { id: ref.id })
42
42
  .getOne();
43
43
  if (!found) {
44
- throw new Error(`user not found in this domain: ${ref.id}`);
44
+ throw new shell_1.Refusal('user-not-in-domain', {}, `user not found in this domain: ${ref.id}`);
45
45
  }
46
46
  return found;
47
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"domain-reference.js","sourceRoot":"","sources":["../../server/service/domain-reference.ts"],"names":[],"mappings":";;AAgBA,8CAeC;AAMD,oCAmBC;AAtDD,iDAA6D;AAC7D,yDAAgD;AAEhD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,iBAAiB,CACrC,UAAyB,EACzB,GAAuC,EACvC,MAAc,EACd,IAAY;IAEZ,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACvC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAS,EAAE,CAAC,CAAA;IACnG,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,8BAA8B,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,YAAY,CAChC,GAAuC,EACvC,MAAc,EACd,EAAkB;IAElB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACvC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,gBAAI,EAAE,EAAE,CAAC;SACxC,kBAAkB,CAAC,MAAM,CAAC;SAC1B,SAAS,CAAC,cAAc,EAAE,QAAQ,EAAE,uBAAuB,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;SACrF,KAAK,CAAC,eAAe,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;SACtC,MAAM,EAAE,CAAA;IAEX,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;IAC7D,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import { EntityManager, ObjectLiteral, Repository } from 'typeorm'\n\nimport { Domain, getRepository } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\n\n/*\n * A record a patch points at, looked up inside the caller's domain.\n *\n * The lookups this replaces asked by id alone, so a mutation run in one domain could make its\n * department's manager, or its employee's supervisor, a row of another domain: the id was all it\n * took. The answer here is the same three as `checkedParent`:\n *\n * key absent, or undefined undefined — leave the reference as it is\n * null, or no id null — clear it\n * an id the row — refused when the domain has no such row\n */\nexport async function referenceInDomain<T extends ObjectLiteral>(\n repository: Repository<T>,\n ref: { id?: string } | null | undefined,\n domain: Domain,\n what: string\n): Promise<T | null | undefined> {\n if (ref === undefined) return undefined\n if (ref === null || !ref.id) return null\n\n const found = await repository.findOne({ where: { domain: { id: domain.id }, id: ref.id } as any })\n if (!found) {\n throw new Error(`${what} not found in this domain: ${ref.id}`)\n }\n\n return found\n}\n\n/*\n * A user is not owned by a domain the way an employee is — it belongs to several, through\n * `users_domains`. The one an employee is connected to has to be among this domain's users.\n */\nexport async function userInDomain(\n ref: { id?: string } | null | undefined,\n domain: Domain,\n tx?: EntityManager\n): Promise<User | null | undefined> {\n if (ref === undefined) return undefined\n if (ref === null || !ref.id) return null\n\n const found = await getRepository(User, tx)\n .createQueryBuilder('user')\n .innerJoin('user.domains', 'domain', 'domain.id = :domainId', { domainId: domain.id })\n .where('user.id = :id', { id: ref.id })\n .getOne()\n\n if (!found) {\n throw new Error(`user not found in this domain: ${ref.id}`)\n }\n\n return found\n}\n"]}
1
+ {"version":3,"file":"domain-reference.js","sourceRoot":"","sources":["../../server/service/domain-reference.ts"],"names":[],"mappings":";;AAgBA,8CAeC;AAMD,oCAmBC;AAtDD,iDAAsE;AACtE,yDAAgD;AAEhD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,iBAAiB,CACrC,UAAyB,EACzB,GAAuC,EACvC,MAAc,EACd,IAA6C;IAE7C,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACvC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAS,EAAE,CAAC,CAAA;IACnG,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,eAAO,CAAC,GAAG,IAAI,gBAAgB,EAAE,EAAE,EAAE,GAAG,IAAI,8BAA8B,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;IAC/F,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,YAAY,CAChC,GAAuC,EACvC,MAAc,EACd,EAAkB;IAElB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACvC,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IAExC,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,gBAAI,EAAE,EAAE,CAAC;SACxC,kBAAkB,CAAC,MAAM,CAAC;SAC1B,SAAS,CAAC,cAAc,EAAE,QAAQ,EAAE,uBAAuB,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;SACrF,KAAK,CAAC,eAAe,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;SACtC,MAAM,EAAE,CAAA;IAEX,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,eAAO,CAAC,oBAAoB,EAAE,EAAE,EAAE,kCAAkC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;IACzF,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import { EntityManager, ObjectLiteral, Repository } from 'typeorm'\n\nimport { Domain, getRepository, Refusal } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\n\n/*\n * A record a patch points at, looked up inside the caller's domain.\n *\n * The lookups this replaces asked by id alone, so a mutation run in one domain could make its\n * department's manager, or its employee's supervisor, a row of another domain: the id was all it\n * took. The answer here is the same three as `checkedParent`:\n *\n * key absent, or undefined undefined — leave the reference as it is\n * null, or no id null — clear it\n * an id the row — refused when the domain has no such row\n */\nexport async function referenceInDomain<T extends ObjectLiteral>(\n repository: Repository<T>,\n ref: { id?: string } | null | undefined,\n domain: Domain,\n what: 'manager' | 'supervisor' | 'department'\n): Promise<T | null | undefined> {\n if (ref === undefined) return undefined\n if (ref === null || !ref.id) return null\n\n const found = await repository.findOne({ where: { domain: { id: domain.id }, id: ref.id } as any })\n if (!found) {\n throw new Refusal(`${what}-not-in-domain`, {}, `${what} not found in this domain: ${ref.id}`)\n }\n\n return found\n}\n\n/*\n * A user is not owned by a domain the way an employee is — it belongs to several, through\n * `users_domains`. The one an employee is connected to has to be among this domain's users.\n */\nexport async function userInDomain(\n ref: { id?: string } | null | undefined,\n domain: Domain,\n tx?: EntityManager\n): Promise<User | null | undefined> {\n if (ref === undefined) return undefined\n if (ref === null || !ref.id) return null\n\n const found = await getRepository(User, tx)\n .createQueryBuilder('user')\n .innerJoin('user.domains', 'domain', 'domain.id = :domainId', { domainId: domain.id })\n .where('user.id = :id', { id: ref.id })\n .getOne()\n\n if (!found) {\n throw new Refusal('user-not-in-domain', {}, `user not found in this domain: ${ref.id}`)\n }\n\n return found\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { EntityManager } from 'typeorm';
2
+ /**
3
+ * A 관리 번호 names one live employee in the domain. The unique index carries `deletedAt`, which is NULL on every live
4
+ * row, and NULLs are never equal - so the index does not hold two live employees apart; this does, on the domain as the
5
+ * save leaves it. A row without an `id` is new; one with an `id` that leaves `controlNo` out keeps its own.
6
+ */
7
+ export declare function refuseTakenControlNos(tx: EntityManager, domain: {
8
+ id: string;
9
+ }, rows: {
10
+ id?: string;
11
+ controlNo?: string | null;
12
+ }[]): Promise<void>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.refuseTakenControlNos = refuseTakenControlNos;
4
+ const shell_1 = require("@things-factory/shell");
5
+ const employee_1 = require("./employee");
6
+ /**
7
+ * A 관리 번호 names one live employee in the domain. The unique index carries `deletedAt`, which is NULL on every live
8
+ * row, and NULLs are never equal - so the index does not hold two live employees apart; this does, on the domain as the
9
+ * save leaves it. A row without an `id` is new; one with an `id` that leaves `controlNo` out keeps its own.
10
+ */
11
+ async function refuseTakenControlNos(tx, domain, rows) {
12
+ const changing = rows.filter(row => row.controlNo !== undefined);
13
+ for (const { controlNo } of changing)
14
+ if (controlNo === null || String(controlNo).trim() === '')
15
+ throw new shell_1.Refusal('employee-control-no-required', {}, 'controlNo: an employee has one');
16
+ const changed = new Set(changing.map(row => row.id).filter(Boolean));
17
+ const kept = (await tx.getRepository(employee_1.Employee).find({ where: { domain: { id: domain.id } }, select: ['id', 'controlNo'] }))
18
+ .filter(one => !changed.has(one.id))
19
+ .map(one => one.controlNo);
20
+ const after = [...kept];
21
+ for (const { controlNo } of changing) {
22
+ if (after.includes(controlNo))
23
+ throw new shell_1.Refusal('employee-control-no-taken', { value: controlNo }, `controlNo: ${controlNo} is already another employee's`);
24
+ after.push(controlNo);
25
+ }
26
+ }
27
+ //# sourceMappingURL=employee-control-no.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-control-no.js","sourceRoot":"","sources":["../../../server/service/employee/employee-control-no.ts"],"names":[],"mappings":";;AAWA,sDAmBC;AA5BD,iDAA+C;AAE/C,yCAAqC;AAErC;;;;GAIG;AACI,KAAK,UAAU,qBAAqB,CACzC,EAAiB,EACjB,MAAsB,EACtB,IAAkD;IAElD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;IAChE,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,QAAQ;QAClC,IAAI,SAAS,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;YACvD,MAAM,IAAI,eAAO,CAAC,8BAA8B,EAAE,EAAE,EAAE,gCAAgC,CAAC,CAAA;IAE3F,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;IACpE,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,aAAa,CAAC,mBAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;SACxH,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACnC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IACvB,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,QAAQ,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,MAAM,IAAI,eAAO,CAAC,2BAA2B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,cAAc,SAAS,gCAAgC,CAAC,CAAA;QAC5J,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACvB,CAAC;AACH,CAAC","sourcesContent":["import { EntityManager } from 'typeorm'\n\nimport { Refusal } from '@things-factory/shell'\n\nimport { Employee } from './employee'\n\n/**\n * A 관리 번호 names one live employee in the domain. The unique index carries `deletedAt`, which is NULL on every live\n * row, and NULLs are never equal - so the index does not hold two live employees apart; this does, on the domain as the\n * save leaves it. A row without an `id` is new; one with an `id` that leaves `controlNo` out keeps its own.\n */\nexport async function refuseTakenControlNos(\n tx: EntityManager,\n domain: { id: string },\n rows: { id?: string; controlNo?: string | null }[]\n): Promise<void> {\n const changing = rows.filter(row => row.controlNo !== undefined)\n for (const { controlNo } of changing)\n if (controlNo === null || String(controlNo).trim() === '')\n throw new Refusal('employee-control-no-required', {}, 'controlNo: an employee has one')\n\n const changed = new Set(changing.map(row => row.id).filter(Boolean))\n const kept = (await tx.getRepository(Employee).find({ where: { domain: { id: domain.id } }, select: ['id', 'controlNo'] }))\n .filter(one => !changed.has(one.id))\n .map(one => one.controlNo)\n const after = [...kept]\n for (const { controlNo } of changing) {\n if (after.includes(controlNo)) throw new Refusal('employee-control-no-taken', { value: controlNo }, `controlNo: ${controlNo} is already another employee's`)\n after.push(controlNo)\n }\n}\n"]}
@@ -7,7 +7,10 @@ exports.withDays = withDays;
7
7
  * value that is not a day is turned away instead of being stored — an old export's '2025-12-31T00:00:00.000Z',
8
8
  * a spreadsheet's serial number. An empty cell (the grid's cleared date input sends '') means no day.
9
9
  */
10
+ const shell_1 = require("@things-factory/shell");
10
11
  const DAY_FIELDS = ['hiredOn', 'retiredOn'];
12
+ /* The refusal of each field - the reader sees the field's name, not hiredOn. */
13
+ const DAY_REFUSALS = { hiredOn: 'hired-on-invalid', retiredOn: 'retired-on-invalid' };
11
14
  function toDay(field, value) {
12
15
  if (value === undefined)
13
16
  return undefined;
@@ -20,7 +23,7 @@ function toDay(field, value) {
20
23
  return value;
21
24
  }
22
25
  }
23
- throw new Error(`${field} must be a calendar day in YYYY-MM-DD format: ${JSON.stringify(value)}`);
26
+ throw new shell_1.Refusal(DAY_REFUSALS[field] ?? 'day-invalid', { value: String(value) }, `${field} must be a calendar day in YYYY-MM-DD format: ${JSON.stringify(value)}`);
24
27
  }
25
28
  function withDays(patch) {
26
29
  const result = { ...patch };
@@ -1 +1 @@
1
- {"version":3,"file":"employee-day.js","sourceRoot":"","sources":["../../../server/service/employee/employee-day.ts"],"names":[],"mappings":";;AAOA,sBAaC;AAED,4BAMC;AA5BD;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,WAAW,CAAU,CAAA;AAEpD,SAAgB,KAAK,CAAC,KAAa,EAAE,KAAc;IACjD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACzC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAE/C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACnE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACvD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QACrD,IAAI,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,EAAE,CAAC;YACpG,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iDAAiD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;AACnG,CAAC;AAED,SAAgB,QAAQ,CAAuD,KAAQ;IACrF,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,CAAA;IAC3B,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,KAAK,IAAI,MAAM;YAAG,MAAc,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3E,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["/*\n * hiredOn and retiredOn are calendar days. The GraphQL field is a String, so it takes any text; this is where a\n * value that is not a day is turned away instead of being stored — an old export's '2025-12-31T00:00:00.000Z',\n * a spreadsheet's serial number. An empty cell (the grid's cleared date input sends '') means no day.\n */\nconst DAY_FIELDS = ['hiredOn', 'retiredOn'] as const\n\nexport function toDay(field: string, value: unknown): string | null | undefined {\n if (value === undefined) return undefined\n if (value === null || value === '') return null\n\n if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n const [year, month, day] = value.split('-').map(Number)\n const date = new Date(Date.UTC(year, month - 1, day))\n if (date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day) {\n return value\n }\n }\n\n throw new Error(`${field} must be a calendar day in YYYY-MM-DD format: ${JSON.stringify(value)}`)\n}\n\nexport function withDays<T extends { hiredOn?: unknown; retiredOn?: unknown }>(patch: T): T {\n const result = { ...patch }\n for (const field of DAY_FIELDS) {\n if (field in result) (result as any)[field] = toDay(field, result[field])\n }\n return result\n}\n"]}
1
+ {"version":3,"file":"employee-day.js","sourceRoot":"","sources":["../../../server/service/employee/employee-day.ts"],"names":[],"mappings":";;AAWA,sBAaC;AAED,4BAMC;AAhCD;;;;GAIG;AACH,iDAA+C;AAE/C,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,WAAW,CAAU,CAAA;AACpD,gFAAgF;AAChF,MAAM,YAAY,GAA2B,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAA;AAE7G,SAAgB,KAAK,CAAC,KAAa,EAAE,KAAc;IACjD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACzC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAE/C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACnE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACvD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QACrD,IAAI,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,EAAE,CAAC;YACpG,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;IAED,MAAM,IAAI,eAAO,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,KAAK,iDAAiD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;AACrK,CAAC;AAED,SAAgB,QAAQ,CAAuD,KAAQ;IACrF,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,CAAA;IAC3B,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,KAAK,IAAI,MAAM;YAAG,MAAc,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC3E,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["/*\n * hiredOn and retiredOn are calendar days. The GraphQL field is a String, so it takes any text; this is where a\n * value that is not a day is turned away instead of being stored — an old export's '2025-12-31T00:00:00.000Z',\n * a spreadsheet's serial number. An empty cell (the grid's cleared date input sends '') means no day.\n */\nimport { Refusal } from '@things-factory/shell'\n\nconst DAY_FIELDS = ['hiredOn', 'retiredOn'] as const\n/* The refusal of each field - the reader sees the field's name, not hiredOn. */\nconst DAY_REFUSALS: Record<string, string> = { hiredOn: 'hired-on-invalid', retiredOn: 'retired-on-invalid' }\n\nexport function toDay(field: string, value: unknown): string | null | undefined {\n if (value === undefined) return undefined\n if (value === null || value === '') return null\n\n if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n const [year, month, day] = value.split('-').map(Number)\n const date = new Date(Date.UTC(year, month - 1, day))\n if (date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day) {\n return value\n }\n }\n\n throw new Refusal(DAY_REFUSALS[field] ?? 'day-invalid', { value: String(value) }, `${field} must be a calendar day in YYYY-MM-DD format: ${JSON.stringify(value)}`)\n}\n\nexport function withDays<T extends { hiredOn?: unknown; retiredOn?: unknown }>(patch: T): T {\n const result = { ...patch }\n for (const field of DAY_FIELDS) {\n if (field in result) (result as any)[field] = toDay(field, result[field])\n }\n return result\n}\n"]}
@@ -11,6 +11,7 @@ const employee_1 = require("./employee");
11
11
  const employee_type_1 = require("./employee-type");
12
12
  const department_1 = require("../department/department");
13
13
  const employee_day_1 = require("./employee-day");
14
+ const employee_control_no_1 = require("./employee-control-no");
14
15
  const employee_private_1 = require("./employee-private");
15
16
  const domain_reference_1 = require("../domain-reference");
16
17
  const register_employee_as_system_user_1 = require("../../controllers/register-employee-as-system-user");
@@ -18,6 +19,7 @@ let EmployeeMutation = class EmployeeMutation {
18
19
  async createEmployee(employee, context) {
19
20
  const { domain, user, tx } = context.state;
20
21
  (0, employee_private_1.refusePrivateWrite)([employee]);
22
+ await (0, employee_control_no_1.refuseTakenControlNos)(tx, domain, [{ controlNo: employee.controlNo ?? null }]);
21
23
  const supervisor = await (0, domain_reference_1.referenceInDomain)((0, shell_1.getRepository)(employee_1.Employee, tx), 'supervisor' in employee ? employee.supervisor : undefined, domain, 'supervisor');
22
24
  const department = await (0, domain_reference_1.referenceInDomain)((0, shell_1.getRepository)(department_1.Department, tx), 'department' in employee ? employee.department : undefined, domain, 'department');
23
25
  const connectedUser = await (0, domain_reference_1.userInDomain)('user' in employee ? employee.user : undefined, domain, tx);
@@ -47,12 +49,13 @@ let EmployeeMutation = class EmployeeMutation {
47
49
  const repository = (0, shell_1.getRepository)(employee_1.Employee, tx);
48
50
  const employee = await repository.findOne({ where: { domain: { id: domain.id }, id } });
49
51
  if (!employee)
50
- throw new Error(`There is no employee ${id}.`);
52
+ throw new shell_1.Refusal('employee-not-found', {}, `There is no employee ${id}.`);
51
53
  return await repository.save({ ...employee, bankName: bankName || null, bankAccount: bankAccount || null, updater: user });
52
54
  }
53
55
  async updateEmployee(id, patch, context) {
54
56
  const { domain, user, tx } = context.state;
55
57
  (0, employee_private_1.refusePrivateWrite)([patch]);
58
+ await (0, employee_control_no_1.refuseTakenControlNos)(tx, domain, [{ id, controlNo: patch.controlNo }]);
56
59
  const supervisor = await (0, domain_reference_1.referenceInDomain)((0, shell_1.getRepository)(employee_1.Employee, tx), 'supervisor' in patch ? patch.supervisor : undefined, domain, 'supervisor');
57
60
  const department = await (0, domain_reference_1.referenceInDomain)((0, shell_1.getRepository)(department_1.Department, tx), 'department' in patch ? patch.department : undefined, domain, 'department');
58
61
  const connectedUser = await (0, domain_reference_1.userInDomain)('user' in patch ? patch.user : undefined, domain, tx);
@@ -88,6 +91,10 @@ let EmployeeMutation = class EmployeeMutation {
88
91
  const _createRecords = patches.filter((patch) => patch.cuFlag.toUpperCase() === '+');
89
92
  const _updateRecords = patches.filter((patch) => patch.cuFlag.toUpperCase() === 'M');
90
93
  const employeeRepo = (0, shell_1.getRepository)(employee_1.Employee, tx);
94
+ await (0, employee_control_no_1.refuseTakenControlNos)(tx, domain, [
95
+ ..._createRecords.map(record => ({ controlNo: record.controlNo ?? null })),
96
+ ..._updateRecords.map(record => ({ id: record.id, controlNo: record.controlNo }))
97
+ ]);
91
98
  if (_createRecords.length > 0) {
92
99
  for (let i = 0; i < _createRecords.length; i++) {
93
100
  const newRecord = _createRecords[i];
@@ -125,7 +132,7 @@ let EmployeeMutation = class EmployeeMutation {
125
132
  where: { domain: { id: domain.id }, id: updateRecord.id }
126
133
  });
127
134
  if (!employee) {
128
- throw new Error(`failed to find employee to update: ${updateRecord.id}`);
135
+ throw new shell_1.Refusal('employee-not-found', {}, `failed to find employee to update: ${updateRecord.id}`);
129
136
  }
130
137
  await (0, register_employee_as_system_user_1.onUpdateEmployeeAsSystemUser)(updateRecord, context);
131
138
  const result = await employeeRepo.save({
@@ -173,6 +180,7 @@ let EmployeeMutation = class EmployeeMutation {
173
180
  async importEmployees(employees, context) {
174
181
  const { domain, tx } = context.state;
175
182
  (0, employee_private_1.refusePrivateWrite)(employees);
183
+ await (0, employee_control_no_1.refuseTakenControlNos)(tx, domain, employees.map(employee => ({ id: employee.id, controlNo: employee.id ? employee.controlNo : employee.controlNo ?? null })));
176
184
  await Promise.all(employees.map(async (employee) => {
177
185
  const createdEmployee = await (0, shell_1.getRepository)(employee_1.Employee, tx).save({ domain, ...(0, employee_day_1.withDays)(employee) });
178
186
  }));
@@ -340,6 +348,7 @@ tslib_1.__decorate([
340
348
  tslib_1.__metadata("design:returntype", Promise)
341
349
  ], EmployeeMutation.prototype, "registerEmployeeAsSystemUser", null);
342
350
  exports.EmployeeMutation = EmployeeMutation = tslib_1.__decorate([
343
- (0, type_graphql_1.Resolver)(employee_1.Employee)
351
+ (0, type_graphql_1.Resolver)(employee_1.Employee),
352
+ (0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
344
353
  ], EmployeeMutation);
345
354
  //# sourceMappingURL=employee-mutation.js.map