@things-factory/compliance 10.1.260 → 10.1.261
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.
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/common/employee-reader.d.ts +0 -2
- package/dist-server/service/common/employee-reader.js +0 -12
- package/dist-server/service/common/employee-reader.js.map +1 -1
- package/dist-server/service/compliance-case/compliance-case-service.js +1 -1
- package/dist-server/service/compliance-case/compliance-case-service.js.map +1 -1
- package/dist-server/service/invention/invention-service.js +2 -1
- package/dist-server/service/invention/invention-service.js.map +1 -1
- package/dist-server/service/legal-record/attachment-readers.js +3 -3
- package/dist-server/service/legal-record/attachment-readers.js.map +1 -1
- package/dist-server/service/regulation/regulation-read.js +2 -1
- package/dist-server/service/regulation/regulation-read.js.map +1 -1
- package/dist-server/service/training/training-service.js +4 -3
- package/dist-server/service/training/training-service.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -18
|
@@ -7,5 +7,3 @@ export declare function todayIn(domain: {
|
|
|
7
7
|
export declare function workingEmployeeOf(context: any): Promise<Employee | null>;
|
|
8
8
|
/** The request's employee, refused for an account that is not one - a partner reads no company rule. */
|
|
9
9
|
export declare function requireWorkingEmployee(context: any): Promise<Employee>;
|
|
10
|
-
/** Whether the request holds `category` of this module (`regulation`, `compliance-case` ...) - asked once per request. */
|
|
11
|
-
export declare function holds(context: any, category: string, privilege?: 'query' | 'mutation'): Promise<boolean>;
|
|
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.todayIn = todayIn;
|
|
4
4
|
exports.workingEmployeeOf = workingEmployeeOf;
|
|
5
5
|
exports.requireWorkingEmployee = requireWorkingEmployee;
|
|
6
|
-
exports.holds = holds;
|
|
7
|
-
const auth_base_1 = require("@things-factory/auth-base");
|
|
8
6
|
const my_employee_js_1 = require("@things-factory/organization/dist-server/service/employee/my-employee.js");
|
|
9
7
|
const employee_profile_rules_js_1 = require("@things-factory/organization/dist-server/service/employee-profile/employee-profile-rules.js");
|
|
10
8
|
const shell_1 = require("@things-factory/shell");
|
|
@@ -33,14 +31,4 @@ async function requireWorkingEmployee(context) {
|
|
|
33
31
|
throw new shell_1.Refusal('compliance-employees-only', {}, 'only an employee of this company can do this');
|
|
34
32
|
return employee;
|
|
35
33
|
}
|
|
36
|
-
/** Whether the request holds `category` of this module (`regulation`, `compliance-case` ...) - asked once per request. */
|
|
37
|
-
async function holds(context, category, privilege = 'mutation') {
|
|
38
|
-
const state = context?.state ?? {};
|
|
39
|
-
const { domain, user, unsafeIP, prohibitedPrivileges } = state;
|
|
40
|
-
if (!domain || !user)
|
|
41
|
-
return false;
|
|
42
|
-
const key = `__compliance:${category}:${privilege}`;
|
|
43
|
-
state[key] ??= (0, auth_base_1.checkPermission)({ category, privilege, owner: true }, user, domain, unsafeIP, prohibitedPrivileges).then(Boolean);
|
|
44
|
-
return await state[key];
|
|
45
|
-
}
|
|
46
34
|
//# sourceMappingURL=employee-reader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"employee-reader.js","sourceRoot":"","sources":["../../../server/service/common/employee-reader.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"employee-reader.js","sourceRoot":"","sources":["../../../server/service/common/employee-reader.ts"],"names":[],"mappings":";;AAYA,0BAEC;AAGD,8CAOC;AAGD,wDAIC;AA9BD,6GAAsG;AACtG,2IAA8H;AAC9H,iDAA4D;AAE5D;;;;GAIG;AAEH,iGAAiG;AACjG,SAAgB,OAAO,CAAC,MAAoC,EAAE,MAAY,IAAI,IAAI,EAAE;IAClF,OAAO,IAAA,mBAAW,EAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAA;AAC3C,CAAC;AAED,6FAA6F;AACtF,KAAK,UAAU,iBAAiB,CAAC,OAAY;IAClD,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAA;IAClC,IAAI,KAAK,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACvD,KAAK,CAAC,oBAAoB,GAAG,CAAC,MAAM,IAAA,4BAAW,EAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAA,4CAAgB,EAAC,GAAU,EAAE,KAAK,CAAC,CAAC,IAAI,IAAI,CAAA;IACpH,CAAC;IACD,OAAO,KAAK,CAAC,oBAAoB,CAAA;AACnC,CAAC;AAED,wGAAwG;AACjG,KAAK,UAAU,sBAAsB,CAAC,OAAY;IACvD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAA;IACjD,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,eAAO,CAAC,2BAA2B,EAAE,EAAE,EAAE,8CAA8C,CAAC,CAAA;IACjH,OAAO,QAAQ,CAAA;AACjB,CAAC","sourcesContent":["import { Employee } from '@things-factory/organization'\nimport { myEmployees } from '@things-factory/organization/dist-server/service/employee/my-employee.js'\nimport { isActiveEmployee } from '@things-factory/organization/dist-server/service/employee-profile/employee-profile-rules.js'\nimport { calendarDay, Refusal } from '@things-factory/shell'\n\n/*\n * Who reads the company's legal records (ADR-0187 decisions 7, 8, 21): an employee of the domain - an account tied to an\n * `Employee` still working here - and the holders of the module's tasks. A partner, or an account with no employee\n * record, is neither.\n */\n\n/** The domain's calendar day - the one \"today\" every deadline of this module is counted from. */\nexport function todayIn(domain: { timezone?: string | null }, now: Date = new Date()): string {\n return calendarDay(domain?.timezone, now)\n}\n\n/** The request's employee record still working here, or nothing - asked once per request. */\nexport async function workingEmployeeOf(context: any): Promise<Employee | null> {\n const state = context?.state ?? {}\n if (state.__complianceEmployee === undefined) {\n const today = state.domain ? todayIn(state.domain) : ''\n state.__complianceEmployee = (await myEmployees(context)).find(one => isActiveEmployee(one as any, today)) ?? null\n }\n return state.__complianceEmployee\n}\n\n/** The request's employee, refused for an account that is not one - a partner reads no company rule. */\nexport async function requireWorkingEmployee(context: any): Promise<Employee> {\n const employee = await workingEmployeeOf(context)\n if (!employee) throw new Refusal('compliance-employees-only', {}, 'only an employee of this company can do this')\n return employee\n}\n\n"]}
|
|
@@ -54,7 +54,7 @@ async function caseViewerOf(context) {
|
|
|
54
54
|
const state = context.state;
|
|
55
55
|
state.__complianceCaseViewer ??= (async () => ({
|
|
56
56
|
userId: state.user.id,
|
|
57
|
-
handler: await (0,
|
|
57
|
+
handler: await (0, auth_base_1.requestHolds)(context, exports.CASE_CATEGORY, 'query'),
|
|
58
58
|
employeeIds: (await (0, my_employee_js_1.myEmployees)(context)).map(one => one.id)
|
|
59
59
|
}))();
|
|
60
60
|
return await state.__complianceCaseViewer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compliance-case-service.js","sourceRoot":"","sources":["../../../server/service/compliance-case/compliance-case-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Attachment, createAttachment } from '@things-factory/attachment-base'\nimport { buildDomainUsersQueryBuilder, findDomainOwnerUserIds, getDomainAssignees, recordAuditAction, registerAuditKind, Role, User, UserStatus } from '@things-factory/auth-base'\nimport { translatorFor } from '@things-factory/i18n-base/translator'\nimport { sendNoticeWhenCommitted, type Notice } from '@things-factory/notification'\nimport { Employee } from '@things-factory/organization'\nimport { myEmployees } from '@things-factory/organization/dist-server/service/employee/my-employee.js'\nimport { Setting } from '@things-factory/setting-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam, Refusal } from '@things-factory/shell'\n\nimport { recordCorrections } from '../common/correction'\nimport { holds, requireWorkingEmployee, todayIn } from '../common/employee-reader'\nimport { ComplianceCase, ComplianceCaseEntry, ComplianceCaseStatus } from './compliance-case'\nimport {\n caseHandlingRefusal,\n caseReportRefusal,\n CaseFacts,\n CaseSight,\n caseSightOf,\n caseStatusOf,\n CaseViewer,\n dayPlus,\n HANDLING_FIELDS,\n handlersLeft,\n INVESTIGATION_DAYS_SETTING,\n investigationDaysOf,\n investigationLate\n} from './compliance-case-rules'\nimport { ComplianceCaseHandling, ComplianceCasePerson, ComplianceReportView, NewComplianceCase, NewComplianceCaseReport } from './compliance-case-type'\n\n/*\n * 신고 사건 (ADR-0187 decision 21) and the database. Every door that hands out a case - a list, one case, a file - asks\n * `caseSightOf` here on the server and writes the read to the audit record (ADR-0141 §3.3: the service records the\n * targets it handled). Nothing of a case is registered for AI reading or search, and the notice of a new one carries\n * no word of it.\n */\n\n/** The files of a report hang on the case under this `refType`, those of the investigation on its entries (attachment-base). */\nexport const CASE_REF_TYPE = 'ComplianceCase'\nexport const CASE_ENTRY_REF_TYPE = 'ComplianceCaseEntry'\n/** The privilege category of the case handlers (`compliance.case-handling`). */\nexport const CASE_CATEGORY = 'compliance-case'\n\n/* A read of a case is an event of its own; `sight` says how much was read - FULL or PARTY. */\nregisterAuditKind('compliance-case.read', ['sight'])\n\nconst RELATIONS = ['accused', 'investigators']\nconst text = (value: unknown) => (typeof value === 'string' && value.trim() ? value.trim() : null)\n\n/** The request's person as a case sees them - asked once per request. */\nexport async function caseViewerOf(context: any): Promise<CaseViewer> {\n const state = context.state\n state.__complianceCaseViewer ??= (async () => ({\n userId: state.user.id,\n handler: await holds(context, CASE_CATEGORY, 'query'),\n employeeIds: (await myEmployees(context)).map(one => one.id)\n }))()\n return await state.__complianceCaseViewer\n}\n\n/** The accounts of employees, by employee id. */\nasync function usersOfEmployees(ids: readonly string[], tx?: EntityManager): Promise<Map<string, string>> {\n if (!ids.length) return new Map()\n const employees = await getRepository(Employee, tx).find({ where: { id: In([...ids]) } as any })\n return new Map(employees.filter(one => one.userId).map(one => [one.id, one.userId!]))\n}\n\n/** What the reading rule needs of a case loaded with its accused and investigators. */\nexport async function factsOf(row: ComplianceCase, tx?: EntityManager): Promise<CaseFacts> {\n const accusedEmployeeIds = (row.accused ?? []).map(one => one.id)\n const users = await usersOfEmployees([...accusedEmployeeIds, ...(row.victimId ? [row.victimId] : [])], tx)\n return {\n reporterUserId: row.reporterUserId,\n victimUserId: row.victimId ? users.get(row.victimId) ?? null : null,\n accusedUserIds: accusedEmployeeIds.map(id => users.get(id)).filter(Boolean) as string[],\n accusedEmployeeIds,\n investigatorIds: (row.investigators ?? []).map(one => one.id)\n }\n}\n\n/** The case and what the request reads of it - one answer, `null`, for \"none\" and \"not yours\". */\nexport async function caseInSight(id: string, context: any, tx?: EntityManager): Promise<{ row: ComplianceCase; sight: CaseSight } | null> {\n const { domain } = context.state\n if (!id || !/^[0-9a-f-]{36}$/i.test(id)) return null\n const row = await getRepository(ComplianceCase, tx).findOne({ where: { id, domain: { id: domain.id } } as any, relations: RELATIONS })\n if (!row) return null\n const sight = caseSightOf(await factsOf(row, tx), await caseViewerOf(context))\n return sight ? { row, sight } : null\n}\n\n/** Writes that the request read these cases - on its own, so a failed write never holds the answer back (ADR-0141 §4-4). */\nexport async function recordCaseRead(context: any, ids: readonly string[], sight: 'FULL' | 'PARTY'): Promise<void> {\n if (!ids.length) return\n const { domain, user } = context.state\n await recordAuditAction(\n { kind: 'compliance-case.read', targetKind: CASE_REF_TYPE, targetIds: [...ids], targetRole: 'handled', returned: ids.length, detail: { sight } },\n { actorId: user?.id ?? null, domainId: domain?.id ?? null }\n )\n}\n\n/*\n * ---------------------------------------------------------------- the case handlers\n */\n\n/** The users who hold `compliance-case` in the domain - those in a role that gives it, and the domain's owners. */\nexport async function caseHandlerUserIds(domain: Domain, tx?: EntityManager): Promise<string[]> {\n const roles = await getRepository(Role, tx)\n .createQueryBuilder('R')\n .innerJoin('R.privileges', 'P')\n .leftJoinAndSelect('R.users', 'U')\n .where('R.domain = :domain', { domain: domain.id })\n .andWhere('P.category = :category', { category: CASE_CATEGORY })\n .getMany()\n const ids = new Set<string>(roles.flatMap(one => (one.users ?? []).map(user => user.id)))\n for (const owner of await findDomainOwnerUserIds(domain, tx)) ids.add(owner)\n return [...ids]\n}\n\n/** Whether, with these employees reported against, a case handler is left to take it. */\nexport async function insideHandlerLeft(accusedIds: readonly string[], context: any): Promise<boolean> {\n const { domain, tx } = context.state\n const accusedUserIds = [...(await usersOfEmployees(accusedIds, tx)).values()]\n return handlersLeft(await caseHandlerUserIds(domain, tx), accusedUserIds).length > 0\n}\n\n/** The investigation-start days of the domain - its setting, or seven. */\nexport async function investigationDays(domain: Domain, tx?: EntityManager): Promise<number> {\n const setting = await getRepository(Setting, tx).findOne({ where: { domain: { id: domain.id }, name: INVESTIGATION_DAYS_SETTING } as any })\n return investigationDaysOf(setting?.value)\n}\n\n/*\n * ---------------------------------------------------------------- writing a case\n */\n\n/** The sentences in `lng` from this module's translations, the English one where `lng` has none. */\nconst sayIn = (lng: string) => (key: string, english: string) => translatorFor(lng)(key, { defaultValue: english })\n\n/**\n * The words of the notice of a new case - the same for every case: 「새 신고가 있습니다」 and nothing of it, not its\n * kind, not a name. The handler opens the list to read it, and that read is recorded.\n */\nexport function caseNoticeWords(lng: string) {\n const say = sayIn(lng)\n const subject = say('text.compliance-case-notice', 'There is a new report')\n return { subject, body: subject, action: say('button.compliance-case-notice-open', 'Open'), note: '' }\n}\n\n/** Tells the handlers not reported against that there is a new case, once the request's transaction has committed. */\nasync function tellHandlers(context: any, userIds: string[]): Promise<void> {\n const ids = userIds.filter(id => id !== context.state.user?.id)\n if (!ids.length) return\n const people = await getRepository(User, context.state.tx).find({ where: { id: In(ids) } as any })\n const receivers = people.filter(one => one.status === UserStatus.ACTIVATED).map(one => ({ id: one.id, email: one.email, locale: (one as any).locale }))\n if (!receivers.length) return\n const notice: Notice = { type: 'compliance-case', level: 'info', receivers, words: caseNoticeWords, address: 'compliance-case-list', label: 'compliance-case new' }\n sendNoticeWhenCommitted(context, notice)\n}\n\nasync function employeesOf(ids: readonly string[], domain: Domain, tx: EntityManager, field: string): Promise<Employee[]> {\n const wanted = [...new Set(ids)]\n if (!wanted.length) return []\n const found = await tx.getRepository(Employee).find({ where: { id: In(wanted), domain: { id: domain.id } } as any })\n if (found.length !== wanted.length) throw new Refusal(`compliance-case-${field === 'accusedIds' ? 'accused' : field === 'victimId' ? 'victim' : 'reporter'}-unknown`, {}, `${field} must be employees of this domain`)\n return found\n}\n\nasync function attach(files: any[] | undefined, refType: string, refBy: string, context: any) {\n for (const file of files ?? []) await createAttachment(null, { attachment: { file, refType, refBy } } as any, context)\n}\n\n/** Writes one case and tells the handlers left of it - the one way a case comes in, by the reporter or by a handler. */\nasync function writeCase(input: NewComplianceCaseReport, receivedOn: string, reporter: Employee | null, reporterUser: User | null, files: any[] | undefined, context: any): Promise<ComplianceCase> {\n const { domain, user, tx } = context.state\n const refusal = caseReportRefusal(input)\n if (refusal) throw refusal\n const accused = await employeesOf(input.accusedIds, domain, tx, 'accusedIds')\n const [victim] = input.victimId ? await employeesOf([input.victimId], domain, tx, 'victimId') : [null]\n const accusedUserIds = accused.map(one => one.userId).filter(Boolean) as string[]\n const left = handlersLeft(await caseHandlerUserIds(domain, tx), accusedUserIds)\n\n const repository = tx.getRepository(ComplianceCase)\n const saved = await repository.save(\n repository.create({\n domain,\n kind: input.kind,\n reporter,\n reporterUser,\n victim,\n accused,\n occurredOn: text(input.occurredOn),\n description: input.description.trim(),\n receivedOn,\n investigationDueOn: dayPlus(receivedOn, await investigationDays(domain, tx)),\n noInsideHandler: left.length === 0,\n investigators: [],\n status: ComplianceCaseStatus.RECEIVED,\n creator: user,\n updater: user\n } as any) as unknown as ComplianceCase\n )\n await attach(files, CASE_REF_TYPE, saved.id, context)\n if (!saved.noInsideHandler) await tellHandlers(context, left)\n return saved\n}\n\n/** An employee reports a case of their own seeing - a partner, or an account with no employee record, is refused. */\nexport async function reportComplianceCase(input: NewComplianceCaseReport, files: any[] | undefined, context: any): Promise<ComplianceReportView> {\n const { domain, user, tx } = context.state\n const me = await requireWorkingEmployee(context)\n const saved = await writeCase(input, todayIn(domain), me, user, files, context)\n const row = await tx.getRepository(ComplianceCase).findOne({ where: { id: saved.id } as any, relations: RELATIONS })\n return await reportViewOf(row, 'REPORTER', context, tx)\n}\n\n/** A handler writes down a report received another way - by mouth, by mail. One reported against is not its handler. */\nexport async function recordComplianceCase(input: NewComplianceCase, files: any[] | undefined, context: any): Promise<ComplianceCase> {\n const { domain, tx } = context.state\n if (!input.receivedOn || !/^\\d{4}-\\d{2}-\\d{2}$/.test(input.receivedOn)) throw new Refusal('compliance-case-received-on-invalid', {}, 'give the day it was received as YYYY-MM-DD')\n const viewer = await caseViewerOf(context)\n if (viewer.employeeIds.some(id => input.accusedIds?.includes(id))) throw new Refusal('compliance-case-accused-may-not-handle', {}, 'one reported against does not write the case')\n const [reporter] = input.reporterId ? await employeesOf([input.reporterId], domain, tx, 'reporterId') : [null]\n const reporterUser = reporter?.userId ? await tx.getRepository(User).findOne({ where: { id: reporter.userId } as any }) : null\n const saved = await writeCase(input, input.receivedOn, reporter, reporterUser, files, context)\n return (await tx.getRepository(ComplianceCase).findOne({ where: { id: saved.id } as any, relations: RELATIONS }))!\n}\n\n/** The case as one who reads all of it, or refused - one answer for \"none\", \"not yours\" and \"reported against\". */\nasync function fullCase(id: string, context: any, tx: EntityManager): Promise<ComplianceCase> {\n const found = await caseInSight(id, context, tx)\n if (!found || found.sight !== 'FULL') throw new Refusal('compliance-case-not-found', {}, 'the case was not found. reload and try again.')\n return found.row\n}\n\n/** What the handler writes on a case as it goes. A value already written changes with a correction kept. */\nexport async function handleComplianceCase(patch: ComplianceCaseHandling, context: any): Promise<ComplianceCase> {\n const { domain, user, tx } = context.state\n const row = await fullCase(patch.id, context, tx)\n const values: Record<string, any> = {}\n for (const field of HANDLING_FIELDS) if ((patch as any)[field] !== undefined) values[field] = text((patch as any)[field])\n const refusal = caseHandlingRefusal(values, row as any)\n if (refusal) throw refusal\n\n const before: Record<string, any> = { ...row, investigatorIds: (row.investigators ?? []).map(one => one.id).sort().join(',') }\n if (patch.investigatorIds) {\n const wanted = [...new Set(patch.investigatorIds)]\n const people = wanted.length ? await buildDomainUsersQueryBuilder(domain.id, 'USER', tx).andWhere('USER.id IN (:...ids)', { ids: wanted }).getMany() : []\n if (people.length !== wanted.length) throw new Refusal('compliance-case-investigator-unknown', {}, 'an investigator must be a user of this domain')\n const facts = await factsOf(row, tx)\n if (people.some(one => facts.accusedUserIds.includes(one.id))) throw new Refusal('compliance-case-investigator-accused', {}, 'one reported against does not investigate the case')\n row.investigators = people\n }\n Object.assign(row, values)\n const after = { ...values, ...(patch.investigatorIds ? { investigatorIds: (row.investigators ?? []).map(one => one.id).sort().join(',') } : {}) }\n await recordCorrections(tx, domain, user, { kind: CASE_REF_TYPE, id: row.id }, before, after, [...HANDLING_FIELDS, 'investigatorIds'])\n row.status = caseStatusOf(row) as ComplianceCaseStatus\n row.updater = user\n return await tx.getRepository(ComplianceCase).save(row)\n}\n\n/** One entry of the investigation record - written once, never changed. */\nexport async function addComplianceCaseEntry(caseId: string, writtenOn: string, body: string, files: any[] | undefined, context: any): Promise<ComplianceCaseEntry> {\n const { domain, user, tx } = context.state\n const row = await fullCase(caseId, context, tx)\n if (row.closedOn) throw new Refusal('compliance-case-closed', {}, 'a closed case is not written on')\n if (!writtenOn || !/^\\d{4}-\\d{2}-\\d{2}$/.test(writtenOn)) throw new Refusal('compliance-case-written-on-invalid', {}, 'give the day as YYYY-MM-DD')\n if (!body?.trim()) throw new Refusal('compliance-case-entry-required', {}, 'write what the entry records')\n const repository = tx.getRepository(ComplianceCaseEntry)\n const saved = await repository.save(repository.create({ domain, complianceCase: row, writtenOn, body: body.trim(), creator: user } as any) as unknown as ComplianceCaseEntry)\n await attach(files, CASE_ENTRY_REF_TYPE, saved.id, context)\n return saved\n}\n\n/*\n * ---------------------------------------------------------------- reading cases\n */\n\n/** The cases the handler reads, a page of them - never one they are reported against. */\nexport async function complianceCasesFor(params: ListParam, context: any): Promise<{ items: ComplianceCase[]; total: number }> {\n const { domain } = context.state\n const viewer = await caseViewerOf(context)\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: getRepository(ComplianceCase),\n searchables: [],\n alias: 'cc',\n defaultSortings: [{ name: 'receivedOn', desc: true }]\n })\n if (viewer.employeeIds.length) {\n const against = getRepository(ComplianceCase)\n .createQueryBuilder('ac')\n .select('ac.id')\n .innerJoin('ac.accused', 'accused')\n .where('accused.id IN (:...mine)')\n queryBuilder.andWhere(`cc.id NOT IN (${against.getQuery()})`, { mine: viewer.employeeIds })\n }\n if (!viewer.handler) queryBuilder.andWhere('1 = 0')\n const [items, total] = await queryBuilder.getManyAndCount()\n await recordCaseRead(context, items.map(one => one.id), 'FULL')\n return { items, total }\n}\n\n/** The cases the request investigates - for an investigator who is no handler, an outside labour attorney. */\nexport async function myInvestigations(context: any): Promise<ComplianceCase[]> {\n const { domain, user } = context.state\n const rows = await getRepository(ComplianceCase)\n .createQueryBuilder('cc')\n .innerJoin('cc.investigators', 'investigator', 'investigator.id = :me', { me: user.id })\n .where('cc.domain = :domain', { domain: domain.id })\n .orderBy('cc.receivedOn', 'DESC')\n .getMany()\n const viewer = await caseViewerOf(context)\n const kept: ComplianceCase[] = []\n for (const one of rows) {\n const full = await getRepository(ComplianceCase).findOne({ where: { id: one.id } as any, relations: RELATIONS })\n if (full && caseSightOf(await factsOf(full), viewer) === 'FULL') kept.push(full)\n }\n await recordCaseRead(context, kept.map(one => one.id), 'FULL')\n return kept\n}\n\n/** One case, whole - for its handlers and investigators. */\nexport async function complianceCaseFor(id: string, context: any): Promise<ComplianceCase> {\n const row = await fullCase(id, context, context.state.tx)\n await recordCaseRead(context, [row.id], 'FULL')\n return row\n}\n\n/** A case as the reporter or the victim reads it - what they may, and no field of the investigation. */\nasync function reportViewOf(row: ComplianceCase, standing: 'REPORTER' | 'VICTIM', context: any, tx?: EntityManager): Promise<ComplianceReportView> {\n const reporter = standing === 'REPORTER'\n const victim = reporter && row.victimId ? await getRepository(Employee, tx).findOne({ where: { id: row.victimId } as any }) : null\n const files = reporter\n ? await getRepository(Attachment, tx).find({ where: { domain: { id: context.state.domain.id }, refType: CASE_REF_TYPE, refBy: row.id, creator: { id: context.state.user.id } } as any })\n : []\n return {\n id: row.id,\n kind: row.kind,\n status: row.status,\n standing,\n receivedOn: row.receivedOn,\n noInsideHandler: row.noInsideHandler,\n ...(reporter ? { occurredOn: row.occurredOn, description: row.description, accusedNames: (row.accused ?? []).map(one => one.name), victimName: victim?.name, attachments: files } : {}),\n protectionMeasures: row.protectionMeasures,\n victimOpinion: row.victimOpinion,\n resultNotice: row.resultToldOn ? row.resultNotice : null,\n resultToldOn: row.resultToldOn,\n closedOn: row.closedOn\n } as ComplianceReportView\n}\n\n/** The cases the request reported, or that happened to them - each as a party reads it. */\nexport async function myComplianceReports(context: any): Promise<ComplianceReportView[]> {\n const { domain, user } = context.state\n const viewer = await caseViewerOf(context)\n const queryBuilder = getRepository(ComplianceCase).createQueryBuilder('cc').where('cc.domain = :domain', { domain: domain.id })\n if (viewer.employeeIds.length) queryBuilder.andWhere('(cc.reporterUser = :me OR cc.victim IN (:...mine))', { me: user.id, mine: viewer.employeeIds })\n else queryBuilder.andWhere('cc.reporterUser = :me', { me: user.id })\n const rows = await queryBuilder.orderBy('cc.receivedOn', 'DESC').getMany()\n const views: ComplianceReportView[] = []\n for (const one of rows) {\n const row = await getRepository(ComplianceCase).findOne({ where: { id: one.id } as any, relations: RELATIONS })\n const facts = await factsOf(row!)\n /* The party view, whatever more the reader may read on the handlers' side. */\n const party = caseSightOf(facts, { ...viewer, handler: false })\n if (party) views.push(await reportViewOf(row!, facts.reporterUserId === user.id ? 'REPORTER' : 'VICTIM', context))\n }\n await recordCaseRead(context, views.map(one => one.id), 'PARTY')\n return views\n}\n\n/** The employees still working here a reporter may name, found by name - for a working employee only. */\nexport async function casePeople(words: string, context: any): Promise<ComplianceCasePerson[]> {\n const { domain } = context.state\n await requireWorkingEmployee(context)\n const wanted = (words ?? '').trim().toLowerCase()\n if (!wanted) return []\n const today = todayIn(domain)\n const employees = await getRepository(Employee).find({ where: { domain: { id: domain.id } } as any, order: { name: 'ASC' } as any })\n return employees\n .filter(one => one.active !== false && (!one.retiredOn || one.retiredOn > today) && one.name?.toLowerCase().includes(wanted))\n .slice(0, 20)\n .map(one => ({ id: one.id, name: one.name, note: one.controlNo }))\n}\n\n/** The users of the domain a handler may name as investigators, found by name or mail. */\nexport async function investigatorChoices(words: string, context: any): Promise<ComplianceCasePerson[]> {\n const wanted = (words ?? '').trim().toLowerCase()\n if (!wanted) return []\n return (await getDomainAssignees(context.state.domain))\n .filter(one => `${one.name ?? ''} ${one.email ?? ''}`.toLowerCase().includes(wanted))\n .slice(0, 20)\n .map(one => ({ id: one.id, name: one.name || one.email, note: one.email }))\n}\n\n/*\n * ---------------------------------------------------------------- files\n */\n\n/**\n * Who opens a file of a case. The report's files: those who read all of it, and the reporter their own. The\n * investigation's files: those who read all of it. Every opening is a read of the case, recorded.\n */\nexport async function mayReadCaseFile(attachment: Attachment, context: any): Promise<boolean> {\n const entry = attachment.refType === CASE_ENTRY_REF_TYPE\n const caseId = entry ? (await getRepository(ComplianceCaseEntry).findOne({ where: { id: attachment.refBy } as any }))?.complianceCaseId : attachment.refBy\n const found = caseId ? await caseInSight(caseId, context) : null\n if (!found) return false\n const allowed = found.sight === 'FULL' || (!entry && found.row.reporterUserId === context.state.user.id && attachment.creatorId === context.state.user.id)\n if (allowed) await recordCaseRead(context, [found.row.id], found.sight!)\n return allowed\n}\n\n/*\n * ---------------------------------------------------------------- the management check (ADR-0146)\n */\n\n/**\n * Cases past their investigation-start day with no investigation started (decision 21). Only the day and the count -\n * a check is read by more than the case handlers, so nothing of a case is in it. A case that came in with every handler\n * reported against is not on it: the handlers who read the check are those it is against.\n */\nexport async function complianceCasesNotInvestigated(tx: EntityManager, domain: Domain, today: string): Promise<{ id: string; receivedOn: string; investigationDueOn: string }[]> {\n const open = await tx.getRepository(ComplianceCase).find({ where: { domain: { id: domain.id }, noInsideHandler: false } as any, order: { receivedOn: 'ASC' } as any })\n return open.filter(one => investigationLate(one, today)).map(one => ({ id: one.id, receivedOn: one.receivedOn, investigationDueOn: one.investigationDueOn! }))\n}\n"]}
|
|
1
|
+
{"version":3,"file":"compliance-case-service.js","sourceRoot":"","sources":["../../../server/service/compliance-case/compliance-case-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { Attachment, createAttachment } from '@things-factory/attachment-base'\nimport { buildDomainUsersQueryBuilder, findDomainOwnerUserIds, getDomainAssignees, recordAuditAction, registerAuditKind, requestHolds, Role, User, UserStatus } from '@things-factory/auth-base'\nimport { translatorFor } from '@things-factory/i18n-base/translator'\nimport { sendNoticeWhenCommitted, type Notice } from '@things-factory/notification'\nimport { Employee } from '@things-factory/organization'\nimport { myEmployees } from '@things-factory/organization/dist-server/service/employee/my-employee.js'\nimport { Setting } from '@things-factory/setting-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam, Refusal } from '@things-factory/shell'\n\nimport { recordCorrections } from '../common/correction'\nimport { requireWorkingEmployee, todayIn } from '../common/employee-reader'\nimport { ComplianceCase, ComplianceCaseEntry, ComplianceCaseStatus } from './compliance-case'\nimport {\n caseHandlingRefusal,\n caseReportRefusal,\n CaseFacts,\n CaseSight,\n caseSightOf,\n caseStatusOf,\n CaseViewer,\n dayPlus,\n HANDLING_FIELDS,\n handlersLeft,\n INVESTIGATION_DAYS_SETTING,\n investigationDaysOf,\n investigationLate\n} from './compliance-case-rules'\nimport { ComplianceCaseHandling, ComplianceCasePerson, ComplianceReportView, NewComplianceCase, NewComplianceCaseReport } from './compliance-case-type'\n\n/*\n * 신고 사건 (ADR-0187 decision 21) and the database. Every door that hands out a case - a list, one case, a file - asks\n * `caseSightOf` here on the server and writes the read to the audit record (ADR-0141 §3.3: the service records the\n * targets it handled). Nothing of a case is registered for AI reading or search, and the notice of a new one carries\n * no word of it.\n */\n\n/** The files of a report hang on the case under this `refType`, those of the investigation on its entries (attachment-base). */\nexport const CASE_REF_TYPE = 'ComplianceCase'\nexport const CASE_ENTRY_REF_TYPE = 'ComplianceCaseEntry'\n/** The privilege category of the case handlers (`compliance.case-handling`). */\nexport const CASE_CATEGORY = 'compliance-case'\n\n/* A read of a case is an event of its own; `sight` says how much was read - FULL or PARTY. */\nregisterAuditKind('compliance-case.read', ['sight'])\n\nconst RELATIONS = ['accused', 'investigators']\nconst text = (value: unknown) => (typeof value === 'string' && value.trim() ? value.trim() : null)\n\n/** The request's person as a case sees them - asked once per request. */\nexport async function caseViewerOf(context: any): Promise<CaseViewer> {\n const state = context.state\n state.__complianceCaseViewer ??= (async () => ({\n userId: state.user.id,\n handler: await requestHolds(context, CASE_CATEGORY, 'query'),\n employeeIds: (await myEmployees(context)).map(one => one.id)\n }))()\n return await state.__complianceCaseViewer\n}\n\n/** The accounts of employees, by employee id. */\nasync function usersOfEmployees(ids: readonly string[], tx?: EntityManager): Promise<Map<string, string>> {\n if (!ids.length) return new Map()\n const employees = await getRepository(Employee, tx).find({ where: { id: In([...ids]) } as any })\n return new Map(employees.filter(one => one.userId).map(one => [one.id, one.userId!]))\n}\n\n/** What the reading rule needs of a case loaded with its accused and investigators. */\nexport async function factsOf(row: ComplianceCase, tx?: EntityManager): Promise<CaseFacts> {\n const accusedEmployeeIds = (row.accused ?? []).map(one => one.id)\n const users = await usersOfEmployees([...accusedEmployeeIds, ...(row.victimId ? [row.victimId] : [])], tx)\n return {\n reporterUserId: row.reporterUserId,\n victimUserId: row.victimId ? users.get(row.victimId) ?? null : null,\n accusedUserIds: accusedEmployeeIds.map(id => users.get(id)).filter(Boolean) as string[],\n accusedEmployeeIds,\n investigatorIds: (row.investigators ?? []).map(one => one.id)\n }\n}\n\n/** The case and what the request reads of it - one answer, `null`, for \"none\" and \"not yours\". */\nexport async function caseInSight(id: string, context: any, tx?: EntityManager): Promise<{ row: ComplianceCase; sight: CaseSight } | null> {\n const { domain } = context.state\n if (!id || !/^[0-9a-f-]{36}$/i.test(id)) return null\n const row = await getRepository(ComplianceCase, tx).findOne({ where: { id, domain: { id: domain.id } } as any, relations: RELATIONS })\n if (!row) return null\n const sight = caseSightOf(await factsOf(row, tx), await caseViewerOf(context))\n return sight ? { row, sight } : null\n}\n\n/** Writes that the request read these cases - on its own, so a failed write never holds the answer back (ADR-0141 §4-4). */\nexport async function recordCaseRead(context: any, ids: readonly string[], sight: 'FULL' | 'PARTY'): Promise<void> {\n if (!ids.length) return\n const { domain, user } = context.state\n await recordAuditAction(\n { kind: 'compliance-case.read', targetKind: CASE_REF_TYPE, targetIds: [...ids], targetRole: 'handled', returned: ids.length, detail: { sight } },\n { actorId: user?.id ?? null, domainId: domain?.id ?? null }\n )\n}\n\n/*\n * ---------------------------------------------------------------- the case handlers\n */\n\n/** The users who hold `compliance-case` in the domain - those in a role that gives it, and the domain's owners. */\nexport async function caseHandlerUserIds(domain: Domain, tx?: EntityManager): Promise<string[]> {\n const roles = await getRepository(Role, tx)\n .createQueryBuilder('R')\n .innerJoin('R.privileges', 'P')\n .leftJoinAndSelect('R.users', 'U')\n .where('R.domain = :domain', { domain: domain.id })\n .andWhere('P.category = :category', { category: CASE_CATEGORY })\n .getMany()\n const ids = new Set<string>(roles.flatMap(one => (one.users ?? []).map(user => user.id)))\n for (const owner of await findDomainOwnerUserIds(domain, tx)) ids.add(owner)\n return [...ids]\n}\n\n/** Whether, with these employees reported against, a case handler is left to take it. */\nexport async function insideHandlerLeft(accusedIds: readonly string[], context: any): Promise<boolean> {\n const { domain, tx } = context.state\n const accusedUserIds = [...(await usersOfEmployees(accusedIds, tx)).values()]\n return handlersLeft(await caseHandlerUserIds(domain, tx), accusedUserIds).length > 0\n}\n\n/** The investigation-start days of the domain - its setting, or seven. */\nexport async function investigationDays(domain: Domain, tx?: EntityManager): Promise<number> {\n const setting = await getRepository(Setting, tx).findOne({ where: { domain: { id: domain.id }, name: INVESTIGATION_DAYS_SETTING } as any })\n return investigationDaysOf(setting?.value)\n}\n\n/*\n * ---------------------------------------------------------------- writing a case\n */\n\n/** The sentences in `lng` from this module's translations, the English one where `lng` has none. */\nconst sayIn = (lng: string) => (key: string, english: string) => translatorFor(lng)(key, { defaultValue: english })\n\n/**\n * The words of the notice of a new case - the same for every case: 「새 신고가 있습니다」 and nothing of it, not its\n * kind, not a name. The handler opens the list to read it, and that read is recorded.\n */\nexport function caseNoticeWords(lng: string) {\n const say = sayIn(lng)\n const subject = say('text.compliance-case-notice', 'There is a new report')\n return { subject, body: subject, action: say('button.compliance-case-notice-open', 'Open'), note: '' }\n}\n\n/** Tells the handlers not reported against that there is a new case, once the request's transaction has committed. */\nasync function tellHandlers(context: any, userIds: string[]): Promise<void> {\n const ids = userIds.filter(id => id !== context.state.user?.id)\n if (!ids.length) return\n const people = await getRepository(User, context.state.tx).find({ where: { id: In(ids) } as any })\n const receivers = people.filter(one => one.status === UserStatus.ACTIVATED).map(one => ({ id: one.id, email: one.email, locale: (one as any).locale }))\n if (!receivers.length) return\n const notice: Notice = { type: 'compliance-case', level: 'info', receivers, words: caseNoticeWords, address: 'compliance-case-list', label: 'compliance-case new' }\n sendNoticeWhenCommitted(context, notice)\n}\n\nasync function employeesOf(ids: readonly string[], domain: Domain, tx: EntityManager, field: string): Promise<Employee[]> {\n const wanted = [...new Set(ids)]\n if (!wanted.length) return []\n const found = await tx.getRepository(Employee).find({ where: { id: In(wanted), domain: { id: domain.id } } as any })\n if (found.length !== wanted.length) throw new Refusal(`compliance-case-${field === 'accusedIds' ? 'accused' : field === 'victimId' ? 'victim' : 'reporter'}-unknown`, {}, `${field} must be employees of this domain`)\n return found\n}\n\nasync function attach(files: any[] | undefined, refType: string, refBy: string, context: any) {\n for (const file of files ?? []) await createAttachment(null, { attachment: { file, refType, refBy } } as any, context)\n}\n\n/** Writes one case and tells the handlers left of it - the one way a case comes in, by the reporter or by a handler. */\nasync function writeCase(input: NewComplianceCaseReport, receivedOn: string, reporter: Employee | null, reporterUser: User | null, files: any[] | undefined, context: any): Promise<ComplianceCase> {\n const { domain, user, tx } = context.state\n const refusal = caseReportRefusal(input)\n if (refusal) throw refusal\n const accused = await employeesOf(input.accusedIds, domain, tx, 'accusedIds')\n const [victim] = input.victimId ? await employeesOf([input.victimId], domain, tx, 'victimId') : [null]\n const accusedUserIds = accused.map(one => one.userId).filter(Boolean) as string[]\n const left = handlersLeft(await caseHandlerUserIds(domain, tx), accusedUserIds)\n\n const repository = tx.getRepository(ComplianceCase)\n const saved = await repository.save(\n repository.create({\n domain,\n kind: input.kind,\n reporter,\n reporterUser,\n victim,\n accused,\n occurredOn: text(input.occurredOn),\n description: input.description.trim(),\n receivedOn,\n investigationDueOn: dayPlus(receivedOn, await investigationDays(domain, tx)),\n noInsideHandler: left.length === 0,\n investigators: [],\n status: ComplianceCaseStatus.RECEIVED,\n creator: user,\n updater: user\n } as any) as unknown as ComplianceCase\n )\n await attach(files, CASE_REF_TYPE, saved.id, context)\n if (!saved.noInsideHandler) await tellHandlers(context, left)\n return saved\n}\n\n/** An employee reports a case of their own seeing - a partner, or an account with no employee record, is refused. */\nexport async function reportComplianceCase(input: NewComplianceCaseReport, files: any[] | undefined, context: any): Promise<ComplianceReportView> {\n const { domain, user, tx } = context.state\n const me = await requireWorkingEmployee(context)\n const saved = await writeCase(input, todayIn(domain), me, user, files, context)\n const row = await tx.getRepository(ComplianceCase).findOne({ where: { id: saved.id } as any, relations: RELATIONS })\n return await reportViewOf(row, 'REPORTER', context, tx)\n}\n\n/** A handler writes down a report received another way - by mouth, by mail. One reported against is not its handler. */\nexport async function recordComplianceCase(input: NewComplianceCase, files: any[] | undefined, context: any): Promise<ComplianceCase> {\n const { domain, tx } = context.state\n if (!input.receivedOn || !/^\\d{4}-\\d{2}-\\d{2}$/.test(input.receivedOn)) throw new Refusal('compliance-case-received-on-invalid', {}, 'give the day it was received as YYYY-MM-DD')\n const viewer = await caseViewerOf(context)\n if (viewer.employeeIds.some(id => input.accusedIds?.includes(id))) throw new Refusal('compliance-case-accused-may-not-handle', {}, 'one reported against does not write the case')\n const [reporter] = input.reporterId ? await employeesOf([input.reporterId], domain, tx, 'reporterId') : [null]\n const reporterUser = reporter?.userId ? await tx.getRepository(User).findOne({ where: { id: reporter.userId } as any }) : null\n const saved = await writeCase(input, input.receivedOn, reporter, reporterUser, files, context)\n return (await tx.getRepository(ComplianceCase).findOne({ where: { id: saved.id } as any, relations: RELATIONS }))!\n}\n\n/** The case as one who reads all of it, or refused - one answer for \"none\", \"not yours\" and \"reported against\". */\nasync function fullCase(id: string, context: any, tx: EntityManager): Promise<ComplianceCase> {\n const found = await caseInSight(id, context, tx)\n if (!found || found.sight !== 'FULL') throw new Refusal('compliance-case-not-found', {}, 'the case was not found. reload and try again.')\n return found.row\n}\n\n/** What the handler writes on a case as it goes. A value already written changes with a correction kept. */\nexport async function handleComplianceCase(patch: ComplianceCaseHandling, context: any): Promise<ComplianceCase> {\n const { domain, user, tx } = context.state\n const row = await fullCase(patch.id, context, tx)\n const values: Record<string, any> = {}\n for (const field of HANDLING_FIELDS) if ((patch as any)[field] !== undefined) values[field] = text((patch as any)[field])\n const refusal = caseHandlingRefusal(values, row as any)\n if (refusal) throw refusal\n\n const before: Record<string, any> = { ...row, investigatorIds: (row.investigators ?? []).map(one => one.id).sort().join(',') }\n if (patch.investigatorIds) {\n const wanted = [...new Set(patch.investigatorIds)]\n const people = wanted.length ? await buildDomainUsersQueryBuilder(domain.id, 'USER', tx).andWhere('USER.id IN (:...ids)', { ids: wanted }).getMany() : []\n if (people.length !== wanted.length) throw new Refusal('compliance-case-investigator-unknown', {}, 'an investigator must be a user of this domain')\n const facts = await factsOf(row, tx)\n if (people.some(one => facts.accusedUserIds.includes(one.id))) throw new Refusal('compliance-case-investigator-accused', {}, 'one reported against does not investigate the case')\n row.investigators = people\n }\n Object.assign(row, values)\n const after = { ...values, ...(patch.investigatorIds ? { investigatorIds: (row.investigators ?? []).map(one => one.id).sort().join(',') } : {}) }\n await recordCorrections(tx, domain, user, { kind: CASE_REF_TYPE, id: row.id }, before, after, [...HANDLING_FIELDS, 'investigatorIds'])\n row.status = caseStatusOf(row) as ComplianceCaseStatus\n row.updater = user\n return await tx.getRepository(ComplianceCase).save(row)\n}\n\n/** One entry of the investigation record - written once, never changed. */\nexport async function addComplianceCaseEntry(caseId: string, writtenOn: string, body: string, files: any[] | undefined, context: any): Promise<ComplianceCaseEntry> {\n const { domain, user, tx } = context.state\n const row = await fullCase(caseId, context, tx)\n if (row.closedOn) throw new Refusal('compliance-case-closed', {}, 'a closed case is not written on')\n if (!writtenOn || !/^\\d{4}-\\d{2}-\\d{2}$/.test(writtenOn)) throw new Refusal('compliance-case-written-on-invalid', {}, 'give the day as YYYY-MM-DD')\n if (!body?.trim()) throw new Refusal('compliance-case-entry-required', {}, 'write what the entry records')\n const repository = tx.getRepository(ComplianceCaseEntry)\n const saved = await repository.save(repository.create({ domain, complianceCase: row, writtenOn, body: body.trim(), creator: user } as any) as unknown as ComplianceCaseEntry)\n await attach(files, CASE_ENTRY_REF_TYPE, saved.id, context)\n return saved\n}\n\n/*\n * ---------------------------------------------------------------- reading cases\n */\n\n/** The cases the handler reads, a page of them - never one they are reported against. */\nexport async function complianceCasesFor(params: ListParam, context: any): Promise<{ items: ComplianceCase[]; total: number }> {\n const { domain } = context.state\n const viewer = await caseViewerOf(context)\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: getRepository(ComplianceCase),\n searchables: [],\n alias: 'cc',\n defaultSortings: [{ name: 'receivedOn', desc: true }]\n })\n if (viewer.employeeIds.length) {\n const against = getRepository(ComplianceCase)\n .createQueryBuilder('ac')\n .select('ac.id')\n .innerJoin('ac.accused', 'accused')\n .where('accused.id IN (:...mine)')\n queryBuilder.andWhere(`cc.id NOT IN (${against.getQuery()})`, { mine: viewer.employeeIds })\n }\n if (!viewer.handler) queryBuilder.andWhere('1 = 0')\n const [items, total] = await queryBuilder.getManyAndCount()\n await recordCaseRead(context, items.map(one => one.id), 'FULL')\n return { items, total }\n}\n\n/** The cases the request investigates - for an investigator who is no handler, an outside labour attorney. */\nexport async function myInvestigations(context: any): Promise<ComplianceCase[]> {\n const { domain, user } = context.state\n const rows = await getRepository(ComplianceCase)\n .createQueryBuilder('cc')\n .innerJoin('cc.investigators', 'investigator', 'investigator.id = :me', { me: user.id })\n .where('cc.domain = :domain', { domain: domain.id })\n .orderBy('cc.receivedOn', 'DESC')\n .getMany()\n const viewer = await caseViewerOf(context)\n const kept: ComplianceCase[] = []\n for (const one of rows) {\n const full = await getRepository(ComplianceCase).findOne({ where: { id: one.id } as any, relations: RELATIONS })\n if (full && caseSightOf(await factsOf(full), viewer) === 'FULL') kept.push(full)\n }\n await recordCaseRead(context, kept.map(one => one.id), 'FULL')\n return kept\n}\n\n/** One case, whole - for its handlers and investigators. */\nexport async function complianceCaseFor(id: string, context: any): Promise<ComplianceCase> {\n const row = await fullCase(id, context, context.state.tx)\n await recordCaseRead(context, [row.id], 'FULL')\n return row\n}\n\n/** A case as the reporter or the victim reads it - what they may, and no field of the investigation. */\nasync function reportViewOf(row: ComplianceCase, standing: 'REPORTER' | 'VICTIM', context: any, tx?: EntityManager): Promise<ComplianceReportView> {\n const reporter = standing === 'REPORTER'\n const victim = reporter && row.victimId ? await getRepository(Employee, tx).findOne({ where: { id: row.victimId } as any }) : null\n const files = reporter\n ? await getRepository(Attachment, tx).find({ where: { domain: { id: context.state.domain.id }, refType: CASE_REF_TYPE, refBy: row.id, creator: { id: context.state.user.id } } as any })\n : []\n return {\n id: row.id,\n kind: row.kind,\n status: row.status,\n standing,\n receivedOn: row.receivedOn,\n noInsideHandler: row.noInsideHandler,\n ...(reporter ? { occurredOn: row.occurredOn, description: row.description, accusedNames: (row.accused ?? []).map(one => one.name), victimName: victim?.name, attachments: files } : {}),\n protectionMeasures: row.protectionMeasures,\n victimOpinion: row.victimOpinion,\n resultNotice: row.resultToldOn ? row.resultNotice : null,\n resultToldOn: row.resultToldOn,\n closedOn: row.closedOn\n } as ComplianceReportView\n}\n\n/** The cases the request reported, or that happened to them - each as a party reads it. */\nexport async function myComplianceReports(context: any): Promise<ComplianceReportView[]> {\n const { domain, user } = context.state\n const viewer = await caseViewerOf(context)\n const queryBuilder = getRepository(ComplianceCase).createQueryBuilder('cc').where('cc.domain = :domain', { domain: domain.id })\n if (viewer.employeeIds.length) queryBuilder.andWhere('(cc.reporterUser = :me OR cc.victim IN (:...mine))', { me: user.id, mine: viewer.employeeIds })\n else queryBuilder.andWhere('cc.reporterUser = :me', { me: user.id })\n const rows = await queryBuilder.orderBy('cc.receivedOn', 'DESC').getMany()\n const views: ComplianceReportView[] = []\n for (const one of rows) {\n const row = await getRepository(ComplianceCase).findOne({ where: { id: one.id } as any, relations: RELATIONS })\n const facts = await factsOf(row!)\n /* The party view, whatever more the reader may read on the handlers' side. */\n const party = caseSightOf(facts, { ...viewer, handler: false })\n if (party) views.push(await reportViewOf(row!, facts.reporterUserId === user.id ? 'REPORTER' : 'VICTIM', context))\n }\n await recordCaseRead(context, views.map(one => one.id), 'PARTY')\n return views\n}\n\n/** The employees still working here a reporter may name, found by name - for a working employee only. */\nexport async function casePeople(words: string, context: any): Promise<ComplianceCasePerson[]> {\n const { domain } = context.state\n await requireWorkingEmployee(context)\n const wanted = (words ?? '').trim().toLowerCase()\n if (!wanted) return []\n const today = todayIn(domain)\n const employees = await getRepository(Employee).find({ where: { domain: { id: domain.id } } as any, order: { name: 'ASC' } as any })\n return employees\n .filter(one => one.active !== false && (!one.retiredOn || one.retiredOn > today) && one.name?.toLowerCase().includes(wanted))\n .slice(0, 20)\n .map(one => ({ id: one.id, name: one.name, note: one.controlNo }))\n}\n\n/** The users of the domain a handler may name as investigators, found by name or mail. */\nexport async function investigatorChoices(words: string, context: any): Promise<ComplianceCasePerson[]> {\n const wanted = (words ?? '').trim().toLowerCase()\n if (!wanted) return []\n return (await getDomainAssignees(context.state.domain))\n .filter(one => `${one.name ?? ''} ${one.email ?? ''}`.toLowerCase().includes(wanted))\n .slice(0, 20)\n .map(one => ({ id: one.id, name: one.name || one.email, note: one.email }))\n}\n\n/*\n * ---------------------------------------------------------------- files\n */\n\n/**\n * Who opens a file of a case. The report's files: those who read all of it, and the reporter their own. The\n * investigation's files: those who read all of it. Every opening is a read of the case, recorded.\n */\nexport async function mayReadCaseFile(attachment: Attachment, context: any): Promise<boolean> {\n const entry = attachment.refType === CASE_ENTRY_REF_TYPE\n const caseId = entry ? (await getRepository(ComplianceCaseEntry).findOne({ where: { id: attachment.refBy } as any }))?.complianceCaseId : attachment.refBy\n const found = caseId ? await caseInSight(caseId, context) : null\n if (!found) return false\n const allowed = found.sight === 'FULL' || (!entry && found.row.reporterUserId === context.state.user.id && attachment.creatorId === context.state.user.id)\n if (allowed) await recordCaseRead(context, [found.row.id], found.sight!)\n return allowed\n}\n\n/*\n * ---------------------------------------------------------------- the management check (ADR-0146)\n */\n\n/**\n * Cases past their investigation-start day with no investigation started (decision 21). Only the day and the count -\n * a check is read by more than the case handlers, so nothing of a case is in it. A case that came in with every handler\n * reported against is not on it: the handlers who read the check are those it is against.\n */\nexport async function complianceCasesNotInvestigated(tx: EntityManager, domain: Domain, today: string): Promise<{ id: string; receivedOn: string; investigationDueOn: string }[]> {\n const open = await tx.getRepository(ComplianceCase).find({ where: { domain: { id: domain.id }, noInsideHandler: false } as any, order: { receivedOn: 'ASC' } as any })\n return open.filter(one => investigationLate(one, today)).map(one => ({ id: one.id, receivedOn: one.receivedOn, investigationDueOn: one.investigationDueOn! }))\n}\n"]}
|
|
@@ -11,6 +11,7 @@ exports.inventionColleagues = inventionColleagues;
|
|
|
11
11
|
exports.inventionRewardsOf = inventionRewardsOf;
|
|
12
12
|
exports.inventionDecisionsDue = inventionDecisionsDue;
|
|
13
13
|
const typeorm_1 = require("typeorm");
|
|
14
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
14
15
|
const organization_1 = require("@things-factory/organization");
|
|
15
16
|
const employee_profile_rules_js_1 = require("@things-factory/organization/dist-server/service/employee-profile/employee-profile-rules.js");
|
|
16
17
|
const shell_1 = require("@things-factory/shell");
|
|
@@ -59,7 +60,7 @@ async function visibleInvention(id, context) {
|
|
|
59
60
|
const row = await tx.getRepository(invention_1.Invention).findOne({ where: { id, domain: { id: domain.id } } });
|
|
60
61
|
if (!row)
|
|
61
62
|
throw notFound();
|
|
62
|
-
if (await (0,
|
|
63
|
+
if (await (0, auth_base_1.requestHolds)(context, exports.INVENTION_CATEGORY, 'query'))
|
|
63
64
|
return row;
|
|
64
65
|
if (await isInventor(context, id))
|
|
65
66
|
return row;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invention-service.js","sourceRoot":"","sources":["../../../server/service/invention/invention-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In, IsNull } from 'typeorm'\n\nimport { Department, Employee } from '@things-factory/organization'\nimport { isActiveEmployee } from '@things-factory/organization/dist-server/service/employee-profile/employee-profile-rules.js'\nimport { Refusal } from '@things-factory/shell'\n\nimport { recordCorrections } from '../common/correction'\nimport { holds, requireWorkingEmployee, todayIn, workingEmployeeOf } from '../common/employee-reader'\nimport { LegalRegistration } from '../legal-registration/legal-registration'\nimport { isDay } from '../legal-record/days'\nimport { fieldsOf, managerOf, text } from '../legal-record/legal-record-support'\nimport { Invention, InventionInventor, InventionReward } from './invention'\nimport { inventionDecisionDueOnOf, inventionDecisionDueSoon, inventionDecisionRefusal, inventionReportRefusal, inventionRewardRefusal } from './invention-rules'\nimport { InventionPatch, InventionPerson, InventionRewardPatch, NewInvention } from './invention-type'\n\n/*\n * 직무발명 (ADR-0187 decision 24): an employee reports one, its inventors and the keepers of the records read it, the\n * keepers write what the company decided, the patent filed and the rewards. Nothing is deleted.\n */\n\nexport const INVENTION_CATEGORY = 'invention'\nexport const INVENTION_REF_TYPE = 'compliance-invention'\n\nconst notFound = () => new Refusal('invention-not-found', {}, 'the invention was not found. reload and try again.')\nconst notDeletable = () => new Refusal('legal-record-not-deletable', {}, 'a legal record is never deleted - end it, or correct it')\n\n/** Reports an invention - the reporter is one of its inventors; the decision is due four months on. */\nexport async function reportInvention(input: NewInvention, context: ResolverContext): Promise<Invention> {\n const { domain, user, tx } = context.state\n const reporter = await requireWorkingEmployee(context)\n const inventorIds = [...new Set([reporter.id, ...(input.coInventorIds ?? []).filter(Boolean)])]\n const reportedOn = text(input.reportedOn) ?? todayIn(domain)\n const refusal = inventionReportRefusal({ ...input, reportedOn, inventorIds })\n if (refusal) throw refusal\n const inventors = await tx.getRepository(Employee).find({ where: { id: In(inventorIds), domain: { id: domain.id } } as any })\n if (inventors.length !== inventorIds.length) throw new Refusal('invention-inventor-unknown', {}, 'every inventor must be an employee of this company')\n\n const repository = tx.getRepository(Invention)\n const saved = await repository.save(\n repository.create({ domain, title: text(input.title), content: input.content.trim(), reportedOn, decisionDueOn: inventionDecisionDueOnOf(reportedOn), reporter, creator: user, updater: user } as any) as any\n )\n for (const employee of inventors) await tx.getRepository(InventionInventor).save({ domain, invention: saved, employee } as any)\n return saved\n}\n\n/** Whether the request is one of the invention's inventors. */\nasync function isInventor(context: ResolverContext, inventionId: string): Promise<boolean> {\n const employee = await workingEmployeeOf(context)\n return !!employee && !!(await managerOf(context).getRepository(InventionInventor).count({ where: { invention: { id: inventionId }, employee: { id: employee.id } } as any }))\n}\n\n/** The invention when the request may read it - an inventor, or a holder of the records; refused otherwise. */\nexport async function visibleInvention(id: string, context: ResolverContext): Promise<Invention> {\n const { domain } = context.state\n const tx = managerOf(context)\n const row = await tx.getRepository(Invention).findOne({ where: { id, domain: { id: domain.id } } as any })\n if (!row) throw notFound()\n if (await holds(context, INVENTION_CATEGORY, 'query')) return row\n if (await isInventor(context, id)) return row\n throw new Refusal('invention-not-yours', {}, 'an invention is read by its inventors and those who keep the records')\n}\n\n/** The inventions the request is an inventor of, the latest first. */\nexport async function myInventions(context: ResolverContext): Promise<Invention[]> {\n const { domain } = context.state\n const tx = managerOf(context)\n const employee = await requireWorkingEmployee(context)\n const mine = await tx.getRepository(InventionInventor).find({ where: { employee: { id: employee.id } } as any })\n if (!mine.length) return []\n return await tx.getRepository(Invention).find({ where: { id: In(mine.map(one => one.inventionId)), domain: { id: domain.id } } as any, order: { reportedOn: 'DESC' } as any })\n}\n\n/** What the keepers write on an invention - its text, the decision told, the patent filed, notes. */\nexport async function updateInventions(patches: InventionPatch[], context: ResolverContext): Promise<Invention[]> {\n const { domain, user, tx } = context.state\n const repository = tx.getRepository(Invention)\n const saved: Invention[] = []\n for (const patch of patches) {\n if (patch.cuFlag === '-') throw notDeletable()\n if (patch.cuFlag === '+') throw new Refusal('invention-reported-by-employee', {}, 'an invention is reported by its inventor')\n const row = await repository.findOne({ where: { id: patch.id, domain: { id: domain.id } } as any })\n if (!row) throw notFound()\n const before = { ...row }\n const given = new Set(fieldsOf(patch))\n for (const field of ['title', 'content', 'decision', 'decisionToldOn', 'notes'] as const) if (given.has(field)) (row as any)[field] = text((patch as any)[field])\n if (!row.title || !row.content) throw new Refusal(row.title ? 'invention-content-required' : 'invention-title-required', {}, row.title ? 'say what the invention is' : 'give the invention a title')\n const refusal = inventionDecisionRefusal(row.decision, row.decisionToldOn, row.reportedOn)\n if (refusal) throw refusal\n if (given.has('filingId')) {\n const id = text(patch.filingId)\n const filing = id ? await tx.getRepository(LegalRegistration).findOne({ where: { id, domain: { id: domain.id } } as any }) : null\n if (id && filing?.kind !== 'PATENT') throw new Refusal('invention-filing-not-a-patent', {}, 'the filing is a patent of the ledger')\n row.filing = filing\n }\n row.updater = user\n saved.push(await repository.save(row))\n const after = { ...row, filingId: given.has('filingId') ? (row.filing?.id ?? null) : row.filingId }\n await recordCorrections(tx, domain, user, { kind: 'Invention', id: row.id }, before, after, ['title', 'content', 'decision', 'decisionToldOn', 'notes', 'filingId'])\n }\n return saved\n}\n\n/** Writes the rewards of an invention - a reward is never deleted, a wrong one is corrected. */\nexport async function saveInventionRewards(inventionId: string, patches: InventionRewardPatch[], context: ResolverContext): Promise<InventionReward[]> {\n const { domain, user, tx } = context.state\n const invention = await tx.getRepository(Invention).findOne({ where: { id: inventionId, domain: { id: domain.id } } as any })\n if (!invention) throw notFound()\n const repository = tx.getRepository(InventionReward)\n const saved: InventionReward[] = []\n for (const patch of patches) {\n if (patch.cuFlag === '-') throw notDeletable()\n const row: InventionReward = patch.id ? await repository.findOne({ where: { id: patch.id, invention: { id: invention.id } } as any }) : (repository.create({ domain, invention, creator: user } as any) as any)\n if (!row) throw notFound()\n const before = { ...row }\n if (patch.name !== undefined) row.name = text(patch.name)\n if (patch.amount !== undefined) row.amount = patch.amount\n if (patch.paidOn !== undefined) row.paidOn = text(patch.paidOn)\n if (patch.paymentLink !== undefined) row.paymentLink = text(patch.paymentLink)\n const refusal = inventionRewardRefusal(row)\n if (refusal) throw refusal\n row.updater = user\n saved.push(await repository.save(row))\n await recordCorrections(tx, domain, user, { kind: 'InventionReward', id: row.id }, before, row, ['name', 'amount', 'paidOn', 'paymentLink'])\n }\n return saved\n}\n\nconst personOf = (one: Employee, departments: Map<string, string>): InventionPerson => ({ id: one.id, name: one.name, departmentName: departments.get(one.departmentId) ?? null })\n\nasync function peopleOf(tx: EntityManager, employees: Employee[]): Promise<InventionPerson[]> {\n const ids = [...new Set(employees.map(one => one.departmentId).filter(Boolean))]\n const departments = new Map((ids.length ? await tx.getRepository(Department).find({ where: { id: In(ids) } as any }) : []).map(one => [one.id, one.name] as [string, string]))\n return employees.map(one => personOf(one, departments))\n}\n\n/** An invention's inventors. */\nexport async function inventionInventorsOf(tx: EntityManager, inventionId: string): Promise<InventionPerson[]> {\n const rows = await tx.getRepository(InventionInventor).find({ where: { invention: { id: inventionId } } as any, relations: ['employee'] })\n return await peopleOf(tx, rows.map(one => one.employee).filter(Boolean))\n}\n\n/** The employees still working here, to name as co-inventors - an employee's own door, so it says who and where only. */\nexport async function inventionColleagues(context: ResolverContext): Promise<InventionPerson[]> {\n const { domain } = context.state\n const tx = managerOf(context)\n await requireWorkingEmployee(context)\n const today = todayIn(domain)\n const employees = (await tx.getRepository(Employee).find({ where: { domain: { id: domain.id } } as any, order: { name: 'ASC' } as any })).filter(one => isActiveEmployee(one as any, today))\n return await peopleOf(tx, employees)\n}\n\n/** The rewards of an invention, oldest first. */\nexport async function inventionRewardsOf(tx: EntityManager, inventionId: string): Promise<InventionReward[]> {\n return await tx.getRepository(InventionReward).find({ where: { invention: { id: inventionId } } as any, order: { createdAt: 'ASC' } as any })\n}\n\n/** The management check (ADR-0146): inventions undecided with the decision due within 30 days or past. */\nexport async function inventionDecisionsDue(tx: EntityManager, domain: { id: string }, today: string): Promise<Invention[]> {\n const undecided = await tx.getRepository(Invention).find({ where: { domain: { id: domain.id }, decision: IsNull() } as any, order: { decisionDueOn: 'ASC' } as any })\n return undecided.filter(one => isDay(one.decisionDueOn) && inventionDecisionDueSoon(one, today))\n}\n"]}
|
|
1
|
+
{"version":3,"file":"invention-service.js","sourceRoot":"","sources":["../../../server/service/invention/invention-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In, IsNull } from 'typeorm'\n\nimport { requestHolds } from '@things-factory/auth-base'\nimport { Department, Employee } from '@things-factory/organization'\nimport { isActiveEmployee } from '@things-factory/organization/dist-server/service/employee-profile/employee-profile-rules.js'\nimport { Refusal } from '@things-factory/shell'\n\nimport { recordCorrections } from '../common/correction'\nimport { requireWorkingEmployee, todayIn, workingEmployeeOf } from '../common/employee-reader'\nimport { LegalRegistration } from '../legal-registration/legal-registration'\nimport { isDay } from '../legal-record/days'\nimport { fieldsOf, managerOf, text } from '../legal-record/legal-record-support'\nimport { Invention, InventionInventor, InventionReward } from './invention'\nimport { inventionDecisionDueOnOf, inventionDecisionDueSoon, inventionDecisionRefusal, inventionReportRefusal, inventionRewardRefusal } from './invention-rules'\nimport { InventionPatch, InventionPerson, InventionRewardPatch, NewInvention } from './invention-type'\n\n/*\n * 직무발명 (ADR-0187 decision 24): an employee reports one, its inventors and the keepers of the records read it, the\n * keepers write what the company decided, the patent filed and the rewards. Nothing is deleted.\n */\n\nexport const INVENTION_CATEGORY = 'invention'\nexport const INVENTION_REF_TYPE = 'compliance-invention'\n\nconst notFound = () => new Refusal('invention-not-found', {}, 'the invention was not found. reload and try again.')\nconst notDeletable = () => new Refusal('legal-record-not-deletable', {}, 'a legal record is never deleted - end it, or correct it')\n\n/** Reports an invention - the reporter is one of its inventors; the decision is due four months on. */\nexport async function reportInvention(input: NewInvention, context: ResolverContext): Promise<Invention> {\n const { domain, user, tx } = context.state\n const reporter = await requireWorkingEmployee(context)\n const inventorIds = [...new Set([reporter.id, ...(input.coInventorIds ?? []).filter(Boolean)])]\n const reportedOn = text(input.reportedOn) ?? todayIn(domain)\n const refusal = inventionReportRefusal({ ...input, reportedOn, inventorIds })\n if (refusal) throw refusal\n const inventors = await tx.getRepository(Employee).find({ where: { id: In(inventorIds), domain: { id: domain.id } } as any })\n if (inventors.length !== inventorIds.length) throw new Refusal('invention-inventor-unknown', {}, 'every inventor must be an employee of this company')\n\n const repository = tx.getRepository(Invention)\n const saved = await repository.save(\n repository.create({ domain, title: text(input.title), content: input.content.trim(), reportedOn, decisionDueOn: inventionDecisionDueOnOf(reportedOn), reporter, creator: user, updater: user } as any) as any\n )\n for (const employee of inventors) await tx.getRepository(InventionInventor).save({ domain, invention: saved, employee } as any)\n return saved\n}\n\n/** Whether the request is one of the invention's inventors. */\nasync function isInventor(context: ResolverContext, inventionId: string): Promise<boolean> {\n const employee = await workingEmployeeOf(context)\n return !!employee && !!(await managerOf(context).getRepository(InventionInventor).count({ where: { invention: { id: inventionId }, employee: { id: employee.id } } as any }))\n}\n\n/** The invention when the request may read it - an inventor, or a holder of the records; refused otherwise. */\nexport async function visibleInvention(id: string, context: ResolverContext): Promise<Invention> {\n const { domain } = context.state\n const tx = managerOf(context)\n const row = await tx.getRepository(Invention).findOne({ where: { id, domain: { id: domain.id } } as any })\n if (!row) throw notFound()\n if (await requestHolds(context, INVENTION_CATEGORY, 'query')) return row\n if (await isInventor(context, id)) return row\n throw new Refusal('invention-not-yours', {}, 'an invention is read by its inventors and those who keep the records')\n}\n\n/** The inventions the request is an inventor of, the latest first. */\nexport async function myInventions(context: ResolverContext): Promise<Invention[]> {\n const { domain } = context.state\n const tx = managerOf(context)\n const employee = await requireWorkingEmployee(context)\n const mine = await tx.getRepository(InventionInventor).find({ where: { employee: { id: employee.id } } as any })\n if (!mine.length) return []\n return await tx.getRepository(Invention).find({ where: { id: In(mine.map(one => one.inventionId)), domain: { id: domain.id } } as any, order: { reportedOn: 'DESC' } as any })\n}\n\n/** What the keepers write on an invention - its text, the decision told, the patent filed, notes. */\nexport async function updateInventions(patches: InventionPatch[], context: ResolverContext): Promise<Invention[]> {\n const { domain, user, tx } = context.state\n const repository = tx.getRepository(Invention)\n const saved: Invention[] = []\n for (const patch of patches) {\n if (patch.cuFlag === '-') throw notDeletable()\n if (patch.cuFlag === '+') throw new Refusal('invention-reported-by-employee', {}, 'an invention is reported by its inventor')\n const row = await repository.findOne({ where: { id: patch.id, domain: { id: domain.id } } as any })\n if (!row) throw notFound()\n const before = { ...row }\n const given = new Set(fieldsOf(patch))\n for (const field of ['title', 'content', 'decision', 'decisionToldOn', 'notes'] as const) if (given.has(field)) (row as any)[field] = text((patch as any)[field])\n if (!row.title || !row.content) throw new Refusal(row.title ? 'invention-content-required' : 'invention-title-required', {}, row.title ? 'say what the invention is' : 'give the invention a title')\n const refusal = inventionDecisionRefusal(row.decision, row.decisionToldOn, row.reportedOn)\n if (refusal) throw refusal\n if (given.has('filingId')) {\n const id = text(patch.filingId)\n const filing = id ? await tx.getRepository(LegalRegistration).findOne({ where: { id, domain: { id: domain.id } } as any }) : null\n if (id && filing?.kind !== 'PATENT') throw new Refusal('invention-filing-not-a-patent', {}, 'the filing is a patent of the ledger')\n row.filing = filing\n }\n row.updater = user\n saved.push(await repository.save(row))\n const after = { ...row, filingId: given.has('filingId') ? (row.filing?.id ?? null) : row.filingId }\n await recordCorrections(tx, domain, user, { kind: 'Invention', id: row.id }, before, after, ['title', 'content', 'decision', 'decisionToldOn', 'notes', 'filingId'])\n }\n return saved\n}\n\n/** Writes the rewards of an invention - a reward is never deleted, a wrong one is corrected. */\nexport async function saveInventionRewards(inventionId: string, patches: InventionRewardPatch[], context: ResolverContext): Promise<InventionReward[]> {\n const { domain, user, tx } = context.state\n const invention = await tx.getRepository(Invention).findOne({ where: { id: inventionId, domain: { id: domain.id } } as any })\n if (!invention) throw notFound()\n const repository = tx.getRepository(InventionReward)\n const saved: InventionReward[] = []\n for (const patch of patches) {\n if (patch.cuFlag === '-') throw notDeletable()\n const row: InventionReward = patch.id ? await repository.findOne({ where: { id: patch.id, invention: { id: invention.id } } as any }) : (repository.create({ domain, invention, creator: user } as any) as any)\n if (!row) throw notFound()\n const before = { ...row }\n if (patch.name !== undefined) row.name = text(patch.name)\n if (patch.amount !== undefined) row.amount = patch.amount\n if (patch.paidOn !== undefined) row.paidOn = text(patch.paidOn)\n if (patch.paymentLink !== undefined) row.paymentLink = text(patch.paymentLink)\n const refusal = inventionRewardRefusal(row)\n if (refusal) throw refusal\n row.updater = user\n saved.push(await repository.save(row))\n await recordCorrections(tx, domain, user, { kind: 'InventionReward', id: row.id }, before, row, ['name', 'amount', 'paidOn', 'paymentLink'])\n }\n return saved\n}\n\nconst personOf = (one: Employee, departments: Map<string, string>): InventionPerson => ({ id: one.id, name: one.name, departmentName: departments.get(one.departmentId) ?? null })\n\nasync function peopleOf(tx: EntityManager, employees: Employee[]): Promise<InventionPerson[]> {\n const ids = [...new Set(employees.map(one => one.departmentId).filter(Boolean))]\n const departments = new Map((ids.length ? await tx.getRepository(Department).find({ where: { id: In(ids) } as any }) : []).map(one => [one.id, one.name] as [string, string]))\n return employees.map(one => personOf(one, departments))\n}\n\n/** An invention's inventors. */\nexport async function inventionInventorsOf(tx: EntityManager, inventionId: string): Promise<InventionPerson[]> {\n const rows = await tx.getRepository(InventionInventor).find({ where: { invention: { id: inventionId } } as any, relations: ['employee'] })\n return await peopleOf(tx, rows.map(one => one.employee).filter(Boolean))\n}\n\n/** The employees still working here, to name as co-inventors - an employee's own door, so it says who and where only. */\nexport async function inventionColleagues(context: ResolverContext): Promise<InventionPerson[]> {\n const { domain } = context.state\n const tx = managerOf(context)\n await requireWorkingEmployee(context)\n const today = todayIn(domain)\n const employees = (await tx.getRepository(Employee).find({ where: { domain: { id: domain.id } } as any, order: { name: 'ASC' } as any })).filter(one => isActiveEmployee(one as any, today))\n return await peopleOf(tx, employees)\n}\n\n/** The rewards of an invention, oldest first. */\nexport async function inventionRewardsOf(tx: EntityManager, inventionId: string): Promise<InventionReward[]> {\n return await tx.getRepository(InventionReward).find({ where: { invention: { id: inventionId } } as any, order: { createdAt: 'ASC' } as any })\n}\n\n/** The management check (ADR-0146): inventions undecided with the decision due within 30 days or past. */\nexport async function inventionDecisionsDue(tx: EntityManager, domain: { id: string }, today: string): Promise<Invention[]> {\n const undecided = await tx.getRepository(Invention).find({ where: { domain: { id: domain.id }, decision: IsNull() } as any, order: { decisionDueOn: 'ASC' } as any })\n return undecided.filter(one => isDay(one.decisionDueOn) && inventionDecisionDueSoon(one, today))\n}\n"]}
|
|
@@ -5,14 +5,14 @@ exports.registerLegalRecordFiles = registerLegalRecordFiles;
|
|
|
5
5
|
* Who may open a file of the ledger, an invention or a dispute by its path - whoever may read the record (ADR-0187
|
|
6
6
|
* decisions 23-25). attachment-base has already checked the file is of the request's domain.
|
|
7
7
|
*/
|
|
8
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
8
9
|
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
9
|
-
const employee_reader_1 = require("../common/employee-reader");
|
|
10
10
|
const dispute_service_1 = require("../dispute/dispute-service");
|
|
11
11
|
const invention_service_1 = require("../invention/invention-service");
|
|
12
12
|
const legal_registration_service_1 = require("../legal-registration/legal-registration-service");
|
|
13
13
|
function registerLegalRecordFiles() {
|
|
14
|
-
(0, attachment_base_1.registerAttachmentReader)(legal_registration_service_1.LEGAL_REGISTRATION_REF_TYPE, (_attachment, context) => (0,
|
|
15
|
-
(0, attachment_base_1.registerAttachmentReader)(dispute_service_1.DISPUTE_REF_TYPE, (_attachment, context) => (0,
|
|
14
|
+
(0, attachment_base_1.registerAttachmentReader)(legal_registration_service_1.LEGAL_REGISTRATION_REF_TYPE, (_attachment, context) => (0, auth_base_1.requestHolds)(context, legal_registration_service_1.LEGAL_REGISTRATION_CATEGORY, 'query'));
|
|
15
|
+
(0, attachment_base_1.registerAttachmentReader)(dispute_service_1.DISPUTE_REF_TYPE, (_attachment, context) => (0, auth_base_1.requestHolds)(context, dispute_service_1.DISPUTE_CATEGORY, 'query'));
|
|
16
16
|
(0, attachment_base_1.registerAttachmentReader)(invention_service_1.INVENTION_REF_TYPE, async (attachment, context) => {
|
|
17
17
|
if (!attachment.refBy)
|
|
18
18
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment-readers.js","sourceRoot":"","sources":["../../../server/service/legal-record/attachment-readers.ts"],"names":[],"mappings":";;AAWA,4DAWC;AAtBD;;;GAGG;AACH,qEAA0E;AAE1E
|
|
1
|
+
{"version":3,"file":"attachment-readers.js","sourceRoot":"","sources":["../../../server/service/legal-record/attachment-readers.ts"],"names":[],"mappings":";;AAWA,4DAWC;AAtBD;;;GAGG;AACH,yDAAwD;AACxD,qEAA0E;AAE1E,gEAA+E;AAC/E,sEAAqF;AACrF,iGAA2H;AAE3H,SAAgB,wBAAwB;IACtC,IAAA,0CAAwB,EAAC,wDAA2B,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,IAAA,wBAAY,EAAC,OAAO,EAAE,wDAA2B,EAAE,OAAO,CAAC,CAAC,CAAA;IAC5I,IAAA,0CAAwB,EAAC,kCAAgB,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,IAAA,wBAAY,EAAC,OAAO,EAAE,kCAAgB,EAAE,OAAO,CAAC,CAAC,CAAA;IACtH,IAAA,0CAAwB,EAAC,sCAAkB,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE;QACzE,IAAI,CAAC,UAAU,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QACnC,IAAI,CAAC;YACH,OAAO,CAAC,CAAC,CAAC,MAAM,IAAA,oCAAgB,EAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["/*\n * Who may open a file of the ledger, an invention or a dispute by its path - whoever may read the record (ADR-0187\n * decisions 23-25). attachment-base has already checked the file is of the request's domain.\n */\nimport { requestHolds } from '@things-factory/auth-base'\nimport { registerAttachmentReader } from '@things-factory/attachment-base'\n\nimport { DISPUTE_CATEGORY, DISPUTE_REF_TYPE } from '../dispute/dispute-service'\nimport { INVENTION_REF_TYPE, visibleInvention } from '../invention/invention-service'\nimport { LEGAL_REGISTRATION_CATEGORY, LEGAL_REGISTRATION_REF_TYPE } from '../legal-registration/legal-registration-service'\n\nexport function registerLegalRecordFiles(): void {\n registerAttachmentReader(LEGAL_REGISTRATION_REF_TYPE, (_attachment, context) => requestHolds(context, LEGAL_REGISTRATION_CATEGORY, 'query'))\n registerAttachmentReader(DISPUTE_REF_TYPE, (_attachment, context) => requestHolds(context, DISPUTE_CATEGORY, 'query'))\n registerAttachmentReader(INVENTION_REF_TYPE, async (attachment, context) => {\n if (!attachment.refBy) return false\n try {\n return !!(await visibleInvention(attachment.refBy, context))\n } catch {\n return false\n }\n })\n}\n"]}
|
|
@@ -8,6 +8,7 @@ exports.requireRuleReader = requireRuleReader;
|
|
|
8
8
|
exports.regulationParts = regulationParts;
|
|
9
9
|
exports.registerRegulationReaders = registerRegulationReaders;
|
|
10
10
|
const typeorm_1 = require("typeorm");
|
|
11
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
11
12
|
const announcement_1 = require("@things-factory/announcement");
|
|
12
13
|
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
13
14
|
const help_1 = require("@things-factory/help");
|
|
@@ -22,7 +23,7 @@ const regulation_service_1 = require("./regulation-service");
|
|
|
22
23
|
* procedure and its papers by the keepers of the rules (`regulation`) only. A partner reads none.
|
|
23
24
|
*/
|
|
24
25
|
/** Whether the request keeps the rules. */
|
|
25
|
-
const keepsRules = (context) => (0,
|
|
26
|
+
const keepsRules = (context) => (0, auth_base_1.requestHolds)(context, 'regulation', 'query');
|
|
26
27
|
exports.keepsRules = keepsRules;
|
|
27
28
|
/** Whether the request may read the adopted rules - an employee of the domain, or a keeper. */
|
|
28
29
|
async function readsRules(context) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regulation-read.js","sourceRoot":"","sources":["../../../server/service/regulation/regulation-read.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { receiptsOf } from '@things-factory/announcement'\nimport { registerAttachmentReader } from '@things-factory/attachment-base'\nimport { registerHelpSource, type HelpPart } from '@things-factory/help'\nimport { getRepository, Refusal } from '@things-factory/shell'\n\nimport { holds, todayIn, workingEmployeeOf } from '../common/employee-reader'\nimport { Regulation, RegulationClause, RegulationProcedure, RegulationVersion, RegulationVersionStatus } from './regulation'\nimport { clauseChanges, clausesOf, partsOf, periodOfVersion, standingOf } from './regulation-rules'\nimport { announcementsOfVersions, originalsOf, previousAdopted, proceduresOf, REGULATION_HELP_SOURCE, REGULATION_ORIGINAL_REF_TYPE, REGULATION_PROCEDURE_REF_TYPE } from './regulation-service'\nimport { RegulationVersionView, RegulationView } from './regulation-type'\n\n/*\n * Who reads a company rule (ADR-0187 decision 7), asked by every door - the list, one rule, its papers, the help's search:\n * an adopted version, past ones too, is read by the domain's employees; a version being written or in approval, the\n * procedure and its papers by the keepers of the rules (`regulation`) only. A partner reads none.\n */\n\n/** Whether the request keeps the rules. */\nexport const keepsRules = (context: any) => holds(context, 'regulation', 'query')\n\n/** Whether the request may read the adopted rules - an employee of the domain, or a keeper. */\nexport async function readsRules(context: any): Promise<boolean> {\n return !!(await workingEmployeeOf(context)) || (await keepsRules(context))\n}\n\n/** A version as the request sees it, or nothing when it may not. */\nexport async function viewOfVersion(tx: EntityManager | undefined, context: any, version: RegulationVersion, siblings: RegulationVersion[], keeper: boolean): Promise<RegulationVersionView | null> {\n const { domain, user } = context.state\n if (version.status !== RegulationVersionStatus.ADOPTED && !keeper) return null\n const today = todayIn(domain)\n const standing = standingOf(siblings, today)\n const adopted = siblings.filter(one => one.status === RegulationVersionStatus.ADOPTED && one.effectiveOn).sort((a, b) => (a.effectiveOn! < b.effectiveOn! ? -1 : 1))\n const next = adopted.find(one => one.effectiveOn! > (version.effectiveOn ?? '') && one.id !== version.id)\n const parts = partsOf(version.body)\n const clauses =\n version.status === RegulationVersionStatus.ADOPTED\n ? await getRepository(RegulationClause, tx).find({ where: { version: { id: version.id } } as any, order: { rank: 'ASC' } as any })\n : (parts.clauses.map((one, rank) => ({ id: `${version.id}:${rank}`, rank, versionId: version.id, ...one })) as any[])\n const before = await previousAdopted(getRepository(RegulationVersion, tx).manager, version)\n const changes = clauseChanges(before ? clausesOf(before.body) : [], clausesOf(version.body)).map(one => ({ ...one, title: one.title ?? undefined }))\n const announcement = version.announcementId ? (await announcementsOfVersions(getRepository(RegulationVersion, tx).manager, domain, [version.id])).get(version.id) : undefined\n const receipt = announcement ? (await receiptsOf([announcement.id], user.id, tx)).get(announcement.id) : undefined\n return {\n version,\n period: periodOfVersion(version, standing, today),\n endsOn: version.status === RegulationVersionStatus.ADOPTED ? next?.effectiveOn : undefined,\n clauses,\n appendix: parts.appendix ?? undefined,\n text: parts.clauses.length ? undefined : version.body?.trim() || undefined,\n changes,\n originals: keeper && version.registeredInForce ? ((await originalsOf(getRepository(RegulationVersion, tx).manager, domain, [version.id])).get(version.id) ?? 0) : undefined,\n procedures: keeper ? ((await proceduresOf(getRepository(RegulationVersion, tx).manager, domain, [version.id])) as any) : undefined,\n announcement: keeper ? announcement : undefined,\n told: announcement?.status === 'PUBLISHED',\n readAt: receipt?.acknowledgedAt ?? undefined\n }\n}\n\n/** A rule as the request sees it - its versions, the one in force and the one due. */\nexport async function viewOfRegulation(tx: EntityManager | undefined, context: any, regulation: Regulation, keeper: boolean): Promise<RegulationView> {\n const today = todayIn(context.state.domain)\n const siblings = await getRepository(RegulationVersion, tx).find({ where: { regulation: { id: regulation.id } } as any, order: { version: 'DESC' } as any })\n const views = (await Promise.all(siblings.map(one => viewOfVersion(tx, context, one, siblings, keeper)))).filter(Boolean) as RegulationVersionView[]\n const standing = standingOf(siblings, today)\n return { regulation, inForce: views.find(one => one.version.id === standing.inForce?.id), due: views.find(one => one.version.id === standing.due?.id), versions: views }\n}\n\n/** The request may read the rules, or is refused - a partner is told so. */\nexport async function requireRuleReader(context: any): Promise<boolean> {\n const keeper = await keepsRules(context)\n if (!keeper && !(await workingEmployeeOf(context))) throw new Refusal('compliance-employees-only', {}, 'only an employee of this company reads its rules')\n return keeper\n}\n\n/** The help's parts of the rules: an article of each version in force or due is a part (ADR-0187 decision 12). */\nexport async function regulationParts(domain: { id: string; timezone?: string }): Promise<HelpPart[]> {\n const today = todayIn(domain)\n const regulations = await getRepository(Regulation).find({ where: { domain: { id: domain.id } } as any })\n if (!regulations.length) return []\n const versions = await getRepository(RegulationVersion).find({ where: { regulation: { id: In(regulations.map(one => one.id)) }, status: RegulationVersionStatus.ADOPTED } as any })\n const parts: HelpPart[] = []\n for (const regulation of regulations) {\n const { inForce, due } = standingOf(versions.filter(one => one.regulationId === regulation.id), today)\n for (const version of [inForce, due].filter(Boolean) as RegulationVersion[]) {\n const clauses = await getRepository(RegulationClause).find({ where: { version: { id: version.id } } as any, order: { rank: 'ASC' } as any })\n const when = version === due ? `${version.effectiveOn} 시행 예정` : `${version.effectiveOn} 시행`\n for (const clause of clauses)\n parts.push({\n topic: `${REGULATION_HELP_SOURCE}/${regulation.code}`,\n section: clause.number,\n lang: '',\n title: `${regulation.name} ${clause.heading}`,\n documentTitle: regulation.name,\n summary: `제${version.version}판 · ${when}.`,\n text: `제${version.version}판 · ${when}. ${clause.text}`,\n link: `regulations?regulation=${encodeURIComponent(regulation.code)}&clause=${encodeURIComponent(clause.number)}`\n })\n }\n }\n return parts\n}\n\n/** The rules' articles in the help's search, and the papers of a procedure to its keepers only. */\nexport function registerRegulationReaders(): void {\n registerHelpSource({ name: REGULATION_HELP_SOURCE, partsOf: domain => regulationParts(domain as any), mayRead: readsRules })\n registerAttachmentReader(REGULATION_PROCEDURE_REF_TYPE, async (attachment, context) => {\n if (!attachment.refBy || !(await keepsRules(context))) return false\n return !!(await getRepository(RegulationProcedure).findOne({ where: { id: attachment.refBy, domain: { id: (context as any).state.domain.id } } as any }))\n })\n registerAttachmentReader(REGULATION_ORIGINAL_REF_TYPE, async (attachment, context) => {\n if (!attachment.refBy || !(await keepsRules(context))) return false\n return !!(await getRepository(RegulationVersion).findOne({ where: { id: attachment.refBy, domain: { id: (context as any).state.domain.id } } as any }))\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"regulation-read.js","sourceRoot":"","sources":["../../../server/service/regulation/regulation-read.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\n\nimport { requestHolds } from '@things-factory/auth-base'\nimport { receiptsOf } from '@things-factory/announcement'\nimport { registerAttachmentReader } from '@things-factory/attachment-base'\nimport { registerHelpSource, type HelpPart } from '@things-factory/help'\nimport { getRepository, Refusal } from '@things-factory/shell'\n\nimport { todayIn, workingEmployeeOf } from '../common/employee-reader'\nimport { Regulation, RegulationClause, RegulationProcedure, RegulationVersion, RegulationVersionStatus } from './regulation'\nimport { clauseChanges, clausesOf, partsOf, periodOfVersion, standingOf } from './regulation-rules'\nimport { announcementsOfVersions, originalsOf, previousAdopted, proceduresOf, REGULATION_HELP_SOURCE, REGULATION_ORIGINAL_REF_TYPE, REGULATION_PROCEDURE_REF_TYPE } from './regulation-service'\nimport { RegulationVersionView, RegulationView } from './regulation-type'\n\n/*\n * Who reads a company rule (ADR-0187 decision 7), asked by every door - the list, one rule, its papers, the help's search:\n * an adopted version, past ones too, is read by the domain's employees; a version being written or in approval, the\n * procedure and its papers by the keepers of the rules (`regulation`) only. A partner reads none.\n */\n\n/** Whether the request keeps the rules. */\nexport const keepsRules = (context: any) => requestHolds(context, 'regulation', 'query')\n\n/** Whether the request may read the adopted rules - an employee of the domain, or a keeper. */\nexport async function readsRules(context: any): Promise<boolean> {\n return !!(await workingEmployeeOf(context)) || (await keepsRules(context))\n}\n\n/** A version as the request sees it, or nothing when it may not. */\nexport async function viewOfVersion(tx: EntityManager | undefined, context: any, version: RegulationVersion, siblings: RegulationVersion[], keeper: boolean): Promise<RegulationVersionView | null> {\n const { domain, user } = context.state\n if (version.status !== RegulationVersionStatus.ADOPTED && !keeper) return null\n const today = todayIn(domain)\n const standing = standingOf(siblings, today)\n const adopted = siblings.filter(one => one.status === RegulationVersionStatus.ADOPTED && one.effectiveOn).sort((a, b) => (a.effectiveOn! < b.effectiveOn! ? -1 : 1))\n const next = adopted.find(one => one.effectiveOn! > (version.effectiveOn ?? '') && one.id !== version.id)\n const parts = partsOf(version.body)\n const clauses =\n version.status === RegulationVersionStatus.ADOPTED\n ? await getRepository(RegulationClause, tx).find({ where: { version: { id: version.id } } as any, order: { rank: 'ASC' } as any })\n : (parts.clauses.map((one, rank) => ({ id: `${version.id}:${rank}`, rank, versionId: version.id, ...one })) as any[])\n const before = await previousAdopted(getRepository(RegulationVersion, tx).manager, version)\n const changes = clauseChanges(before ? clausesOf(before.body) : [], clausesOf(version.body)).map(one => ({ ...one, title: one.title ?? undefined }))\n const announcement = version.announcementId ? (await announcementsOfVersions(getRepository(RegulationVersion, tx).manager, domain, [version.id])).get(version.id) : undefined\n const receipt = announcement ? (await receiptsOf([announcement.id], user.id, tx)).get(announcement.id) : undefined\n return {\n version,\n period: periodOfVersion(version, standing, today),\n endsOn: version.status === RegulationVersionStatus.ADOPTED ? next?.effectiveOn : undefined,\n clauses,\n appendix: parts.appendix ?? undefined,\n text: parts.clauses.length ? undefined : version.body?.trim() || undefined,\n changes,\n originals: keeper && version.registeredInForce ? ((await originalsOf(getRepository(RegulationVersion, tx).manager, domain, [version.id])).get(version.id) ?? 0) : undefined,\n procedures: keeper ? ((await proceduresOf(getRepository(RegulationVersion, tx).manager, domain, [version.id])) as any) : undefined,\n announcement: keeper ? announcement : undefined,\n told: announcement?.status === 'PUBLISHED',\n readAt: receipt?.acknowledgedAt ?? undefined\n }\n}\n\n/** A rule as the request sees it - its versions, the one in force and the one due. */\nexport async function viewOfRegulation(tx: EntityManager | undefined, context: any, regulation: Regulation, keeper: boolean): Promise<RegulationView> {\n const today = todayIn(context.state.domain)\n const siblings = await getRepository(RegulationVersion, tx).find({ where: { regulation: { id: regulation.id } } as any, order: { version: 'DESC' } as any })\n const views = (await Promise.all(siblings.map(one => viewOfVersion(tx, context, one, siblings, keeper)))).filter(Boolean) as RegulationVersionView[]\n const standing = standingOf(siblings, today)\n return { regulation, inForce: views.find(one => one.version.id === standing.inForce?.id), due: views.find(one => one.version.id === standing.due?.id), versions: views }\n}\n\n/** The request may read the rules, or is refused - a partner is told so. */\nexport async function requireRuleReader(context: any): Promise<boolean> {\n const keeper = await keepsRules(context)\n if (!keeper && !(await workingEmployeeOf(context))) throw new Refusal('compliance-employees-only', {}, 'only an employee of this company reads its rules')\n return keeper\n}\n\n/** The help's parts of the rules: an article of each version in force or due is a part (ADR-0187 decision 12). */\nexport async function regulationParts(domain: { id: string; timezone?: string }): Promise<HelpPart[]> {\n const today = todayIn(domain)\n const regulations = await getRepository(Regulation).find({ where: { domain: { id: domain.id } } as any })\n if (!regulations.length) return []\n const versions = await getRepository(RegulationVersion).find({ where: { regulation: { id: In(regulations.map(one => one.id)) }, status: RegulationVersionStatus.ADOPTED } as any })\n const parts: HelpPart[] = []\n for (const regulation of regulations) {\n const { inForce, due } = standingOf(versions.filter(one => one.regulationId === regulation.id), today)\n for (const version of [inForce, due].filter(Boolean) as RegulationVersion[]) {\n const clauses = await getRepository(RegulationClause).find({ where: { version: { id: version.id } } as any, order: { rank: 'ASC' } as any })\n const when = version === due ? `${version.effectiveOn} 시행 예정` : `${version.effectiveOn} 시행`\n for (const clause of clauses)\n parts.push({\n topic: `${REGULATION_HELP_SOURCE}/${regulation.code}`,\n section: clause.number,\n lang: '',\n title: `${regulation.name} ${clause.heading}`,\n documentTitle: regulation.name,\n summary: `제${version.version}판 · ${when}.`,\n text: `제${version.version}판 · ${when}. ${clause.text}`,\n link: `regulations?regulation=${encodeURIComponent(regulation.code)}&clause=${encodeURIComponent(clause.number)}`\n })\n }\n }\n return parts\n}\n\n/** The rules' articles in the help's search, and the papers of a procedure to its keepers only. */\nexport function registerRegulationReaders(): void {\n registerHelpSource({ name: REGULATION_HELP_SOURCE, partsOf: domain => regulationParts(domain as any), mayRead: readsRules })\n registerAttachmentReader(REGULATION_PROCEDURE_REF_TYPE, async (attachment, context) => {\n if (!attachment.refBy || !(await keepsRules(context))) return false\n return !!(await getRepository(RegulationProcedure).findOne({ where: { id: attachment.refBy, domain: { id: (context as any).state.domain.id } } as any }))\n })\n registerAttachmentReader(REGULATION_ORIGINAL_REF_TYPE, async (attachment, context) => {\n if (!attachment.refBy || !(await keepsRules(context))) return false\n return !!(await getRepository(RegulationVersion).findOne({ where: { id: attachment.refBy, domain: { id: (context as any).state.domain.id } } as any }))\n })\n}\n"]}
|
|
@@ -25,6 +25,7 @@ exports.mayReadSession = mayReadSession;
|
|
|
25
25
|
const typeorm_1 = require("typeorm");
|
|
26
26
|
const announcement_1 = require("@things-factory/announcement");
|
|
27
27
|
const attachment_base_1 = require("@things-factory/attachment-base");
|
|
28
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
28
29
|
const translator_1 = require("@things-factory/i18n-base/translator");
|
|
29
30
|
const organization_1 = require("@things-factory/organization");
|
|
30
31
|
const employee_profile_rules_js_1 = require("@things-factory/organization/dist-server/service/employee-profile/employee-profile-rules.js");
|
|
@@ -94,7 +95,7 @@ const audienceRows = (audiences) => (audiences ?? []).map(one => ({ scope: one.s
|
|
|
94
95
|
async function trainingReaderOf(context) {
|
|
95
96
|
const { domain } = context.state;
|
|
96
97
|
const tx = trainingManagerOf(context);
|
|
97
|
-
const all = await (0,
|
|
98
|
+
const all = await (0, auth_base_1.requestHolds)(context, 'training', 'query');
|
|
98
99
|
const employee = await (0, employee_reader_1.workingEmployeeOf)(context);
|
|
99
100
|
let headed = [];
|
|
100
101
|
if (employee) {
|
|
@@ -532,7 +533,7 @@ async function myTrainings(year, context) {
|
|
|
532
533
|
async function mayReadCompletion(row, context) {
|
|
533
534
|
if (!row)
|
|
534
535
|
return false;
|
|
535
|
-
if (await (0,
|
|
536
|
+
if (await (0, auth_base_1.requestHolds)(context, 'training', 'query'))
|
|
536
537
|
return true;
|
|
537
538
|
const employee = await (0, employee_reader_1.workingEmployeeOf)(context);
|
|
538
539
|
return !!employee && employee.id === row.employeeId;
|
|
@@ -541,7 +542,7 @@ async function mayReadCompletion(row, context) {
|
|
|
541
542
|
async function mayReadSession(row, context) {
|
|
542
543
|
if (!row)
|
|
543
544
|
return false;
|
|
544
|
-
if (await (0,
|
|
545
|
+
if (await (0, auth_base_1.requestHolds)(context, 'training', 'query'))
|
|
545
546
|
return true;
|
|
546
547
|
const { domain } = context.state;
|
|
547
548
|
const employee = await (0, employee_reader_1.workingEmployeeOf)(context);
|