@things-factory/organization 10.1.212 → 10.1.215
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.
|
@@ -65,7 +65,13 @@ let EmployeeQuery = class EmployeeQuery {
|
|
|
65
65
|
domain,
|
|
66
66
|
params,
|
|
67
67
|
repository: await (0, shell_1.getRepository)(employee_1.Employee),
|
|
68
|
-
|
|
68
|
+
/*
|
|
69
|
+
* A LIKE filter on a field outside this list is dropped with a warning, so a part of a position, a responsibility or a
|
|
70
|
+
* department's name is matched only when listed here (2026-10-24: 「프로 직책인 사람」 read every employee).
|
|
71
|
+
*/
|
|
72
|
+
searchables: ['name', 'controlNo', 'alias', 'active', 'userId', 'jobPosition', 'jobResponsibility', 'departmentName'],
|
|
73
|
+
/* By the department's name - a conversation knows a team by what it is called, never by its id (ai-assistant people list). */
|
|
74
|
+
filtersMap: { departmentName: { columnName: 'name', relationColumn: 'department' } }
|
|
69
75
|
});
|
|
70
76
|
const [items, total] = await queryBuilder.getManyAndCount();
|
|
71
77
|
return { items, total };
|
|
@@ -177,7 +183,7 @@ tslib_1.__decorate([
|
|
|
177
183
|
tslib_1.__decorate([
|
|
178
184
|
(0, type_graphql_1.Directive)('@privilege(category: "employee", privilege: "query", domainOwnerGranted: true)'),
|
|
179
185
|
(0, type_graphql_1.Query)(returns => employee_type_1.EmployeeList, {
|
|
180
|
-
description: 'Fetches a list of employees based on provided query parameters. Supports searching by name, control number, and
|
|
186
|
+
description: 'Fetches a list of employees based on provided query parameters. Supports searching by name, control number, alias, position, responsibility and department name.'
|
|
181
187
|
}),
|
|
182
188
|
tslib_1.__param(0, (0, type_graphql_1.Args)(type => shell_1.ListParam)),
|
|
183
189
|
tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"employee-query.js","sourceRoot":"","sources":["../../../server/service/employee/employee-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\nimport { Attachment } from '@things-factory/attachment-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { Contact, ContactItem, ContactField, Profile } from '@things-factory/contact'\nimport { Employee } from './employee'\nimport { EmployeeList } from './employee-type'\nimport { Department } from '../department/department'\nimport { myEmployees as myEmployeesOf } from './my-employee.js'\n\nasync function getContactItem(contactId: string, type: string, label: string, context: ResolverContext) {\n const { domain } = context.state\n const contact: Contact = await getRepository(Contact).findOne({ where: { domain: { id: domain.id }, id: contactId } })\n const { items } = contact\n\n if (!items || !(items instanceof Array)) {\n return\n }\n\n return items?.find(item => item.type === type && item.label === label)?.value\n}\n\n@Resolver(Employee)\nexport class EmployeeQuery {\n /**\n * 부른 사람 자신의 사원 기록 — **권한을 붙이지 않는다.**\n *\n * ── 왜 필요한가 ──────────────────────────────────────────────────────────\n * 「내 것」 축의 읽기와 쓰기는 이미 권한 없이 있다(`myApprovalLines` · `createMyApprovalLine` ·\n * `updateMyApprovalLine`). 그 자리들이 모두 **사원 기록에 의존하는데, 그것이 있는지 물을 방법이\n * 없었다.**\n *\n * 그래서 사원 기록이 없는 사람에게도 「내 결재선」 화면이 입력을 받았고, 저장을 누른 뒤에야\n * 실패했다. 화면이 알아야 하는 것은 「지금 0건이다」가 아니라 **「너는 이 화면을 쓸 수 없다」**다.\n * 그건 목록이 아니라 자격에 대한 물음이므로 답하는 자리가 따로 있어야 한다.\n *\n * ── 왜 권한이 없나 ──────────────────────────────────────────────────────\n * 「나는 누구인가」는 권한으로 가릴 사실이 아니다. 자기 기록만 답하므로 새는 것이 없다.\n * `employees` 는 `employee:query` 를 요구하는데, 그것으로는 **정작 답이 필요한 일반 사원이 물을 수\n * 없다.**\n *\n * ── 왜 복수인가 ────────────────────────────────────────────────────────\n * `Employee` 에 `(domain, user)` 유일 제약이 없다 — 유일한 것은\n * `(domain, controlNo, deletedAt)` 뿐이다(`employee.ts:36`). 그래서 한 사용자가 한 도메인에서 사원\n * 기록을 둘 이상 가질 수 있고, `myApprovalLines` 도 그것을 전제로 `In(...)` 을 쓴다.\n *\n * 단수로 두면 **없는 제약을 지어내는 것**이 된다. 비어 있으면 빈 배열이다 — 오류가 아니다.\n */\n @Query(returns => [Employee], {\n description: \"Fetches the caller's own employee records in this domain. Empty when the caller is not an employee.\"\n })\n async myEmployees(@Ctx() context: ResolverContext): Promise<Employee[]> {\n /*\n * 조회를 여기서 다시 쓰지 않는다. 「이 사용자의 사원 기록」을 판정하는 자리는 `my-employee.ts`\n * 하나다 — 그 자리가 없어서 같은 물음을 네 곳이 각자 다르게 다루던 것이 이 결함의 원인이었다.\n */\n return await myEmployeesOf(context)\n }\n\n @Directive('@privilege(category: \"employee\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => Employee!, {\n nullable: true,\n description:\n 'Fetches a specific employee by their unique ID. Returns the employee object if found, or null if not found.'\n })\n async employee(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Employee> {\n const { domain } = context.state\n\n return await getRepository(Employee).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Directive('@privilege(category: \"employee\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => EmployeeList, {\n description:\n 'Fetches a list of employees based on provided query parameters. Supports searching by name, control number, and alias.'\n })\n async employees(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<EmployeeList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(Employee),\n searchables: ['name', 'controlNo', 'alias', 'active', 'userId']\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => String, { nullable: true })\n async photo(@Root() employee: Employee): Promise<string | undefined> {\n const attachment: Attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: employee.domainId },\n refType: Employee.name,\n refBy: employee.id\n }\n })\n\n return attachment?.fullpath\n }\n\n @FieldResolver(type => String, { nullable: true })\n async phone(@Root() employee: Employee, @Ctx() context: ResolverContext): Promise<string> {\n if (!employee.contactId) {\n return\n }\n\n return await getContactItem(employee.contactId, ContactField.Phone, 'work', context)\n }\n\n @FieldResolver(type => String, { nullable: true })\n async address(@Root() employee: Employee, @Ctx() context: ResolverContext): Promise<string | undefined> {\n if (!employee.contactId) {\n return\n }\n\n return await getContactItem(employee.contactId, ContactField.Address, 'work', context)\n }\n\n @FieldResolver(type => GraphQLEmailAddress, { nullable: true })\n async email(@Root() employee: Employee, @Ctx() context: ResolverContext): Promise<string | undefined> {\n if (!employee.contactId) {\n return\n }\n\n return await getContactItem(employee.contactId, ContactField.Email, 'work', context)\n }\n\n @FieldResolver(type => Profile)\n async profile(@Root() employee: Employee): Promise<Profile> {\n if (!employee.contactId) {\n return\n }\n\n let contact: Contact = employee.contact\n if (!contact) {\n contact = await getRepository(Contact).findOneBy({\n id: employee.contactId\n })\n\n if (!contact) {\n return\n }\n }\n\n const { id: refBy } = contact\n const { left, top, zoom } = contact.profile || {}\n\n const attachment: Attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: contact.domainId },\n refType: Contact.name,\n refBy\n }\n })\n\n return { left, top, zoom, picture: attachment?.fullpath }\n }\n\n @FieldResolver(type => Department)\n async department(@Root() employee: Employee): Promise<Department> {\n if (employee.departmentId) {\n return await getRepository(Department).findOneBy({ id: employee.departmentId })\n }\n }\n\n @FieldResolver(type => User)\n async user(@Root() employee: Employee): Promise<User> {\n if (employee.userId) {\n return await getRepository(User).findOneBy({ id: employee.userId })\n }\n }\n\n @FieldResolver(type => Employee)\n async supervisor(@Root() employee: Employee): Promise<Employee> {\n if (employee.supervisorId) {\n return await getRepository(Employee).findOneBy({ id: employee.supervisorId })\n }\n }\n\n @FieldResolver(type => Contact)\n async contact(@Root() employee: Employee): Promise<Contact> {\n if (employee.contactId) {\n return await getRepository(Contact).findOneBy({ id: employee.contactId })\n }\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() employee: Employee): Promise<Domain> {\n return await getRepository(Domain).findOneBy({ id: employee.domainId })\n }\n\n @FieldResolver(type => User)\n async updater(@Root() employee: Employee): Promise<User> {\n return await getRepository(User).findOneBy({ id: employee.updaterId })\n }\n\n @FieldResolver(type => User)\n async creator(@Root() employee: Employee): Promise<User> {\n return await getRepository(User).findOneBy({ id: employee.creatorId })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"employee-query.js","sourceRoot":"","sources":["../../../server/service/employee/employee-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'\nimport { GraphQLEmailAddress } from 'graphql-scalars'\nimport { Attachment } from '@things-factory/attachment-base'\nimport { Domain, getQueryBuilderFromListParams, getRepository, ListParam } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\nimport { Contact, ContactItem, ContactField, Profile } from '@things-factory/contact'\nimport { Employee } from './employee'\nimport { EmployeeList } from './employee-type'\nimport { Department } from '../department/department'\nimport { myEmployees as myEmployeesOf } from './my-employee.js'\n\nasync function getContactItem(contactId: string, type: string, label: string, context: ResolverContext) {\n const { domain } = context.state\n const contact: Contact = await getRepository(Contact).findOne({ where: { domain: { id: domain.id }, id: contactId } })\n const { items } = contact\n\n if (!items || !(items instanceof Array)) {\n return\n }\n\n return items?.find(item => item.type === type && item.label === label)?.value\n}\n\n@Resolver(Employee)\nexport class EmployeeQuery {\n /**\n * 부른 사람 자신의 사원 기록 — **권한을 붙이지 않는다.**\n *\n * ── 왜 필요한가 ──────────────────────────────────────────────────────────\n * 「내 것」 축의 읽기와 쓰기는 이미 권한 없이 있다(`myApprovalLines` · `createMyApprovalLine` ·\n * `updateMyApprovalLine`). 그 자리들이 모두 **사원 기록에 의존하는데, 그것이 있는지 물을 방법이\n * 없었다.**\n *\n * 그래서 사원 기록이 없는 사람에게도 「내 결재선」 화면이 입력을 받았고, 저장을 누른 뒤에야\n * 실패했다. 화면이 알아야 하는 것은 「지금 0건이다」가 아니라 **「너는 이 화면을 쓸 수 없다」**다.\n * 그건 목록이 아니라 자격에 대한 물음이므로 답하는 자리가 따로 있어야 한다.\n *\n * ── 왜 권한이 없나 ──────────────────────────────────────────────────────\n * 「나는 누구인가」는 권한으로 가릴 사실이 아니다. 자기 기록만 답하므로 새는 것이 없다.\n * `employees` 는 `employee:query` 를 요구하는데, 그것으로는 **정작 답이 필요한 일반 사원이 물을 수\n * 없다.**\n *\n * ── 왜 복수인가 ────────────────────────────────────────────────────────\n * `Employee` 에 `(domain, user)` 유일 제약이 없다 — 유일한 것은\n * `(domain, controlNo, deletedAt)` 뿐이다(`employee.ts:36`). 그래서 한 사용자가 한 도메인에서 사원\n * 기록을 둘 이상 가질 수 있고, `myApprovalLines` 도 그것을 전제로 `In(...)` 을 쓴다.\n *\n * 단수로 두면 **없는 제약을 지어내는 것**이 된다. 비어 있으면 빈 배열이다 — 오류가 아니다.\n */\n @Query(returns => [Employee], {\n description: \"Fetches the caller's own employee records in this domain. Empty when the caller is not an employee.\"\n })\n async myEmployees(@Ctx() context: ResolverContext): Promise<Employee[]> {\n /*\n * 조회를 여기서 다시 쓰지 않는다. 「이 사용자의 사원 기록」을 판정하는 자리는 `my-employee.ts`\n * 하나다 — 그 자리가 없어서 같은 물음을 네 곳이 각자 다르게 다루던 것이 이 결함의 원인이었다.\n */\n return await myEmployeesOf(context)\n }\n\n @Directive('@privilege(category: \"employee\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => Employee!, {\n nullable: true,\n description:\n 'Fetches a specific employee by their unique ID. Returns the employee object if found, or null if not found.'\n })\n async employee(@Arg('id') id: string, @Ctx() context: ResolverContext): Promise<Employee> {\n const { domain } = context.state\n\n return await getRepository(Employee).findOne({\n where: { domain: { id: domain.id }, id }\n })\n }\n\n @Directive('@privilege(category: \"employee\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => EmployeeList, {\n description:\n 'Fetches a list of employees based on provided query parameters. Supports searching by name, control number, alias, position, responsibility and department name.'\n })\n async employees(@Args(type => ListParam) params: ListParam, @Ctx() context: ResolverContext): Promise<EmployeeList> {\n const { domain } = context.state\n\n const queryBuilder = getQueryBuilderFromListParams({\n domain,\n params,\n repository: await getRepository(Employee),\n /*\n * A LIKE filter on a field outside this list is dropped with a warning, so a part of a position, a responsibility or a\n * department's name is matched only when listed here (2026-10-24: 「프로 직책인 사람」 read every employee).\n */\n searchables: ['name', 'controlNo', 'alias', 'active', 'userId', 'jobPosition', 'jobResponsibility', 'departmentName'],\n /* By the department's name - a conversation knows a team by what it is called, never by its id (ai-assistant people list). */\n filtersMap: { departmentName: { columnName: 'name', relationColumn: 'department' } }\n })\n\n const [items, total] = await queryBuilder.getManyAndCount()\n\n return { items, total }\n }\n\n @FieldResolver(type => String, { nullable: true })\n async photo(@Root() employee: Employee): Promise<string | undefined> {\n const attachment: Attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: employee.domainId },\n refType: Employee.name,\n refBy: employee.id\n }\n })\n\n return attachment?.fullpath\n }\n\n @FieldResolver(type => String, { nullable: true })\n async phone(@Root() employee: Employee, @Ctx() context: ResolverContext): Promise<string> {\n if (!employee.contactId) {\n return\n }\n\n return await getContactItem(employee.contactId, ContactField.Phone, 'work', context)\n }\n\n @FieldResolver(type => String, { nullable: true })\n async address(@Root() employee: Employee, @Ctx() context: ResolverContext): Promise<string | undefined> {\n if (!employee.contactId) {\n return\n }\n\n return await getContactItem(employee.contactId, ContactField.Address, 'work', context)\n }\n\n @FieldResolver(type => GraphQLEmailAddress, { nullable: true })\n async email(@Root() employee: Employee, @Ctx() context: ResolverContext): Promise<string | undefined> {\n if (!employee.contactId) {\n return\n }\n\n return await getContactItem(employee.contactId, ContactField.Email, 'work', context)\n }\n\n @FieldResolver(type => Profile)\n async profile(@Root() employee: Employee): Promise<Profile> {\n if (!employee.contactId) {\n return\n }\n\n let contact: Contact = employee.contact\n if (!contact) {\n contact = await getRepository(Contact).findOneBy({\n id: employee.contactId\n })\n\n if (!contact) {\n return\n }\n }\n\n const { id: refBy } = contact\n const { left, top, zoom } = contact.profile || {}\n\n const attachment: Attachment = await getRepository(Attachment).findOne({\n where: {\n domain: { id: contact.domainId },\n refType: Contact.name,\n refBy\n }\n })\n\n return { left, top, zoom, picture: attachment?.fullpath }\n }\n\n @FieldResolver(type => Department)\n async department(@Root() employee: Employee): Promise<Department> {\n if (employee.departmentId) {\n return await getRepository(Department).findOneBy({ id: employee.departmentId })\n }\n }\n\n @FieldResolver(type => User)\n async user(@Root() employee: Employee): Promise<User> {\n if (employee.userId) {\n return await getRepository(User).findOneBy({ id: employee.userId })\n }\n }\n\n @FieldResolver(type => Employee)\n async supervisor(@Root() employee: Employee): Promise<Employee> {\n if (employee.supervisorId) {\n return await getRepository(Employee).findOneBy({ id: employee.supervisorId })\n }\n }\n\n @FieldResolver(type => Contact)\n async contact(@Root() employee: Employee): Promise<Contact> {\n if (employee.contactId) {\n return await getRepository(Contact).findOneBy({ id: employee.contactId })\n }\n }\n\n @FieldResolver(type => Domain)\n async domain(@Root() employee: Employee): Promise<Domain> {\n return await getRepository(Domain).findOneBy({ id: employee.domainId })\n }\n\n @FieldResolver(type => User)\n async updater(@Root() employee: Employee): Promise<User> {\n return await getRepository(User).findOneBy({ id: employee.updaterId })\n }\n\n @FieldResolver(type => User)\n async creator(@Root() employee: Employee): Promise<User> {\n return await getRepository(User).findOneBy({ id: employee.creatorId })\n }\n}\n"]}
|