@things-factory/organization 10.1.222 → 10.1.226

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist-client/pages/employee-profile/employee-profile-form.d.ts +31 -0
  2. package/dist-client/pages/employee-profile/employee-profile-form.js +86 -0
  3. package/dist-client/pages/employee-profile/employee-profile-form.js.map +1 -0
  4. package/dist-client/pages/employee-profile/employee-profile-list-page.d.ts +38 -0
  5. package/dist-client/pages/employee-profile/employee-profile-list-page.js +164 -0
  6. package/dist-client/pages/employee-profile/employee-profile-list-page.js.map +1 -0
  7. package/dist-client/pages/employee-profile/employee-profile-workbook.d.ts +33 -0
  8. package/dist-client/pages/employee-profile/employee-profile-workbook.js +87 -0
  9. package/dist-client/pages/employee-profile/employee-profile-workbook.js.map +1 -0
  10. package/dist-client/pages/employee-profile/my-employee-profile-page.d.ts +38 -0
  11. package/dist-client/pages/employee-profile/my-employee-profile-page.js +282 -0
  12. package/dist-client/pages/employee-profile/my-employee-profile-page.js.map +1 -0
  13. package/dist-client/route.d.ts +1 -1
  14. package/dist-client/route.js +7 -0
  15. package/dist-client/route.js.map +1 -1
  16. package/dist-client/tsconfig.tsbuildinfo +1 -1
  17. package/dist-server/role-tasks.js +4 -1
  18. package/dist-server/role-tasks.js.map +1 -1
  19. package/dist-server/service/employee-profile/employee-profile-mutation.d.ts +5 -0
  20. package/dist-server/service/employee-profile/employee-profile-mutation.js +45 -0
  21. package/dist-server/service/employee-profile/employee-profile-mutation.js.map +1 -0
  22. package/dist-server/service/employee-profile/employee-profile-query.d.ts +6 -0
  23. package/dist-server/service/employee-profile/employee-profile-query.js +58 -0
  24. package/dist-server/service/employee-profile/employee-profile-query.js.map +1 -0
  25. package/dist-server/service/employee-profile/employee-profile-rows.d.ts +29 -0
  26. package/dist-server/service/employee-profile/employee-profile-rows.js +122 -0
  27. package/dist-server/service/employee-profile/employee-profile-rows.js.map +1 -0
  28. package/dist-server/service/employee-profile/employee-profile-rules.d.ts +55 -0
  29. package/dist-server/service/employee-profile/employee-profile-rules.js +80 -0
  30. package/dist-server/service/employee-profile/employee-profile-rules.js.map +1 -0
  31. package/dist-server/service/employee-profile/employee-profile-type.d.ts +24 -0
  32. package/dist-server/service/employee-profile/employee-profile-type.js +81 -0
  33. package/dist-server/service/employee-profile/employee-profile-type.js.map +1 -0
  34. package/dist-server/service/employee-profile/employee-profile.d.ts +24 -0
  35. package/dist-server/service/employee-profile/employee-profile.js +112 -0
  36. package/dist-server/service/employee-profile/employee-profile.js.map +1 -0
  37. package/dist-server/service/employee-profile/index.d.ts +5 -0
  38. package/dist-server/service/employee-profile/index.js +9 -0
  39. package/dist-server/service/employee-profile/index.js.map +1 -0
  40. package/dist-server/service/index.d.ts +3 -2
  41. package/dist-server/service/index.js +6 -2
  42. package/dist-server/service/index.js.map +1 -1
  43. package/dist-server/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +7 -6
  45. package/tests/employee-profile-db.test.ts +186 -0
  46. package/tests/employee-profile-rules.test.ts +76 -0
  47. package/tests/employee-profile-workbook.test.ts +89 -0
  48. package/things-factory.config.js +3 -0
  49. package/translations/en.json +38 -1
  50. package/translations/es.json +38 -1
  51. package/translations/ja.json +38 -1
  52. package/translations/ko.json +38 -1
  53. package/translations/ms.json +38 -1
  54. package/translations/zh.json +38 -1
@@ -12,6 +12,9 @@ exports.ROLE_TASKS = void 0;
12
12
  exports.ROLE_TASKS = [
13
13
  { id: 'organization.people-reading', grants: [{ category: 'employee', axes: ['query'] }, { category: 'department', axes: ['query'] }] },
14
14
  { id: 'organization.people-keeping', grants: [{ category: 'employee', axes: ['query', 'mutation'] }, { category: 'department', axes: ['query', 'mutation'] }] },
15
- { id: 'organization.pay-accounts', grants: [{ category: 'employee-private', axes: ['query', 'mutation'] }] }
15
+ { id: 'organization.pay-accounts', grants: [{ category: 'employee-private', axes: ['query', 'mutation'] }] },
16
+ /* One's own profile, written by the employee; every active employee's, read to attach to a quotation (ADR-0169 decision 3). */
17
+ { id: 'organization.own-profile', grants: [{ category: 'employee-self', axes: ['query', 'mutation'] }] },
18
+ { id: 'organization.profiles-reading', grants: [{ category: 'employee-profile', axes: ['query'] }] }
16
19
  ];
17
20
  //# sourceMappingURL=role-tasks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"role-tasks.js","sourceRoot":"","sources":["../server/role-tasks.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAIU,QAAA,UAAU,GAAe;IACpC,EAAE,EAAE,EAAE,6BAA6B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;IACvI,EAAE,EAAE,EAAE,6BAA6B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE;IAC/J,EAAE,EAAE,EAAE,2BAA2B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE;CAC7G,CAAA","sourcesContent":["/*\n * The work this module names, for the seats applications build (ADR-0139 decision 11).\n *\n * A task holds whole privileges: each opens everything its doors open, and the words under `task.<id>` in this\n * module's translations say what that is. Seats are put together by applications (`RoleTemplate.tasks`).\n *\n * Data only - `server/index.ts` registers it - so an application's tests read it without starting the framework.\n */\n\nimport type { RoleTask } from '@things-factory/auth-base'\n\nexport const ROLE_TASKS: RoleTask[] = [\n { id: 'organization.people-reading', grants: [{ category: 'employee', axes: ['query'] }, { category: 'department', axes: ['query'] }] },\n { id: 'organization.people-keeping', grants: [{ category: 'employee', axes: ['query', 'mutation'] }, { category: 'department', axes: ['query', 'mutation'] }] },\n { id: 'organization.pay-accounts', grants: [{ category: 'employee-private', axes: ['query', 'mutation'] }] }\n]\n"]}
1
+ {"version":3,"file":"role-tasks.js","sourceRoot":"","sources":["../server/role-tasks.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAIU,QAAA,UAAU,GAAe;IACpC,EAAE,EAAE,EAAE,6BAA6B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;IACvI,EAAE,EAAE,EAAE,6BAA6B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE;IAC/J,EAAE,EAAE,EAAE,2BAA2B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE;IAC5G,+HAA+H;IAC/H,EAAE,EAAE,EAAE,0BAA0B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE;IACxG,EAAE,EAAE,EAAE,+BAA+B,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;CACrG,CAAA","sourcesContent":["/*\n * The work this module names, for the seats applications build (ADR-0139 decision 11).\n *\n * A task holds whole privileges: each opens everything its doors open, and the words under `task.<id>` in this\n * module's translations say what that is. Seats are put together by applications (`RoleTemplate.tasks`).\n *\n * Data only - `server/index.ts` registers it - so an application's tests read it without starting the framework.\n */\n\nimport type { RoleTask } from '@things-factory/auth-base'\n\nexport const ROLE_TASKS: RoleTask[] = [\n { id: 'organization.people-reading', grants: [{ category: 'employee', axes: ['query'] }, { category: 'department', axes: ['query'] }] },\n { id: 'organization.people-keeping', grants: [{ category: 'employee', axes: ['query', 'mutation'] }, { category: 'department', axes: ['query', 'mutation'] }] },\n { id: 'organization.pay-accounts', grants: [{ category: 'employee-private', axes: ['query', 'mutation'] }] },\n /* One's own profile, written by the employee; every active employee's, read to attach to a quotation (ADR-0169 decision 3). */\n { id: 'organization.own-profile', grants: [{ category: 'employee-self', axes: ['query', 'mutation'] }] },\n { id: 'organization.profiles-reading', grants: [{ category: 'employee-profile', axes: ['query'] }] }\n]\n"]}
@@ -0,0 +1,5 @@
1
+ import { EmployeeProfile } from './employee-profile';
2
+ import { EmployeeProfileInput } from './employee-profile-type';
3
+ export declare class EmployeeProfileMutation {
4
+ saveMyEmployeeProfile(profile: EmployeeProfileInput, context: ResolverContext): Promise<EmployeeProfile>;
5
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmployeeProfileMutation = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const type_graphql_1 = require("type-graphql");
6
+ const shell_1 = require("@things-factory/shell");
7
+ const my_employee_js_1 = require("../employee/my-employee.js");
8
+ const employee_profile_1 = require("./employee-profile");
9
+ const employee_profile_rules_1 = require("./employee-profile-rules");
10
+ const employee_profile_type_1 = require("./employee-profile-type");
11
+ /*
12
+ * The employee writes their own profile and nobody else's (ADR-0169 decisions 3 · 4) - no door changes another
13
+ * person's. It is saved as one document, as the screen holds it.
14
+ */
15
+ let EmployeeProfileMutation = class EmployeeProfileMutation {
16
+ async saveMyEmployeeProfile(profile, context) {
17
+ const { domain, user, tx } = context.state;
18
+ const employee = await (0, my_employee_js_1.requireMyEmployee)(context);
19
+ const repository = (0, shell_1.getRepository)(employee_profile_1.EmployeeProfile, tx);
20
+ const held = await repository.findOne({ where: { domain: { id: domain.id }, employee: { id: employee.id } } });
21
+ const saved = await repository.save({
22
+ ...(held ?? { domain, employee, creator: user }),
23
+ ...(0, employee_profile_rules_1.profileDocumentOf)(profile),
24
+ updater: user
25
+ });
26
+ return await repository.findOne({ where: { id: saved.id } });
27
+ }
28
+ };
29
+ exports.EmployeeProfileMutation = EmployeeProfileMutation;
30
+ tslib_1.__decorate([
31
+ (0, type_graphql_1.Directive)('@transaction'),
32
+ (0, type_graphql_1.Directive)('@privilege(category: "employee-self", privilege: "mutation", domainOwnerGranted: true)'),
33
+ (0, type_graphql_1.Mutation)(returns => employee_profile_1.EmployeeProfile, {
34
+ description: "Saves the caller's own profile whole - what is left out is emptied. Refused when the account is not linked to exactly one employee."
35
+ }),
36
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('profile', type => employee_profile_type_1.EmployeeProfileInput)),
37
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
38
+ tslib_1.__metadata("design:type", Function),
39
+ tslib_1.__metadata("design:paramtypes", [employee_profile_type_1.EmployeeProfileInput, Object]),
40
+ tslib_1.__metadata("design:returntype", Promise)
41
+ ], EmployeeProfileMutation.prototype, "saveMyEmployeeProfile", null);
42
+ exports.EmployeeProfileMutation = EmployeeProfileMutation = tslib_1.__decorate([
43
+ (0, type_graphql_1.Resolver)(employee_profile_1.EmployeeProfile)
44
+ ], EmployeeProfileMutation);
45
+ //# sourceMappingURL=employee-profile-mutation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-profile-mutation.js","sourceRoot":"","sources":["../../../server/service/employee-profile/employee-profile-mutation.ts"],"names":[],"mappings":";;;;AAAA,+CAAsE;AAEtE,iDAAqD;AAErD,+DAA8D;AAC9D,yDAAoD;AACpD,qEAA4D;AAC5D,mEAA8D;AAE9D;;;GAGG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAM5B,AAAN,KAAK,CAAC,qBAAqB,CAA+C,OAA6B,EAAS,OAAwB;QACtI,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QAC1C,MAAM,QAAQ,GAAG,MAAM,IAAA,kCAAiB,EAAC,OAAO,CAAC,CAAA;QACjD,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,kCAAe,EAAE,EAAE,CAAC,CAAA;QACrD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAE9G,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC;YAClC,GAAG,CAAC,IAAI,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAChD,GAAG,IAAA,0CAAiB,EAAC,OAAO,CAAC;YAC7B,OAAO,EAAE,IAAI;SACK,CAAC,CAAA;QAErB,OAAO,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAC9D,CAAC;CACF,CAAA;AApBY,0DAAuB;AAM5B;IALL,IAAA,wBAAS,EAAC,cAAc,CAAC;IACzB,IAAA,wBAAS,EAAC,wFAAwF,CAAC;IACnG,IAAA,uBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC,kCAAe,EAAE;QACpC,WAAW,EAAE,qIAAqI;KACnJ,CAAC;IAC2B,mBAAA,IAAA,kBAAG,EAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,4CAAoB,CAAC,CAAA;IAAiC,mBAAA,IAAA,kBAAG,GAAE,CAAA;;6CAA5B,4CAAoB;;oEAatG;kCAnBU,uBAAuB;IADnC,IAAA,uBAAQ,EAAC,kCAAe,CAAC;GACb,uBAAuB,CAoBnC","sourcesContent":["import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { requireMyEmployee } from '../employee/my-employee.js'\nimport { EmployeeProfile } from './employee-profile'\nimport { profileDocumentOf } from './employee-profile-rules'\nimport { EmployeeProfileInput } from './employee-profile-type'\n\n/*\n * The employee writes their own profile and nobody else's (ADR-0169 decisions 3 · 4) - no door changes another\n * person's. It is saved as one document, as the screen holds it.\n */\n@Resolver(EmployeeProfile)\nexport class EmployeeProfileMutation {\n @Directive('@transaction')\n @Directive('@privilege(category: \"employee-self\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Mutation(returns => EmployeeProfile, {\n description: \"Saves the caller's own profile whole - what is left out is emptied. Refused when the account is not linked to exactly one employee.\"\n })\n async saveMyEmployeeProfile(@Arg('profile', type => EmployeeProfileInput) profile: EmployeeProfileInput, @Ctx() context: ResolverContext): Promise<EmployeeProfile> {\n const { domain, user, tx } = context.state\n const employee = await requireMyEmployee(context)\n const repository = getRepository(EmployeeProfile, tx)\n const held = await repository.findOne({ where: { domain: { id: domain.id }, employee: { id: employee.id } } })\n\n const saved = await repository.save({\n ...(held ?? { domain, employee, creator: user }),\n ...profileDocumentOf(profile),\n updater: user\n } as EmployeeProfile)\n\n return await repository.findOne({ where: { id: saved.id } })\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { EmployeeProfile } from './employee-profile';
2
+ import { EmployeeWithProfile } from './employee-profile-type';
3
+ export declare class EmployeeProfileQuery {
4
+ myEmployeeProfile(context: ResolverContext): Promise<EmployeeProfile | null>;
5
+ employeeProfiles(context: ResolverContext): Promise<EmployeeWithProfile[]>;
6
+ }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmployeeProfileQuery = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const type_graphql_1 = require("type-graphql");
6
+ const shell_1 = require("@things-factory/shell");
7
+ const employee_1 = require("../employee/employee");
8
+ const my_employee_js_1 = require("../employee/my-employee.js");
9
+ const employee_profile_1 = require("./employee-profile");
10
+ const employee_profile_rules_1 = require("./employee-profile-rules");
11
+ const employee_profile_type_1 = require("./employee-profile-type");
12
+ /*
13
+ * Reading profiles (ADR-0169 decisions 3 · 4): one's own under `employee-self`, every active employee's under
14
+ * `employee-profile` - the seats that attach profiles to quotations. Neither reads the employee record beyond the
15
+ * basics a profile sheet shows.
16
+ */
17
+ let EmployeeProfileQuery = class EmployeeProfileQuery {
18
+ async myEmployeeProfile(context) {
19
+ const { domain, tx } = context.state;
20
+ const mine = await (0, my_employee_js_1.myEmployees)(context);
21
+ if (!mine.length)
22
+ return null;
23
+ const employee = (0, my_employee_js_1.theOneEmployee)(mine, context);
24
+ return await (0, shell_1.getRepository)(employee_profile_1.EmployeeProfile, tx).findOne({ where: { domain: { id: domain.id }, employee: { id: employee.id } } });
25
+ }
26
+ async employeeProfiles(context) {
27
+ const { domain, tx } = context.state;
28
+ const employees = await (0, shell_1.getRepository)(employee_1.Employee, tx).find({ where: { domain: { id: domain.id } }, relations: ['department'] });
29
+ const profiles = await (0, shell_1.getRepository)(employee_profile_1.EmployeeProfile, tx).find({ where: { domain: { id: domain.id } } });
30
+ return (0, employee_profile_rules_1.employeesWithProfiles)(employees, profiles, (0, employee_profile_rules_1.todayOf)());
31
+ }
32
+ };
33
+ exports.EmployeeProfileQuery = EmployeeProfileQuery;
34
+ tslib_1.__decorate([
35
+ (0, type_graphql_1.Directive)('@privilege(category: "employee-self", privilege: "query", domainOwnerGranted: true)'),
36
+ (0, type_graphql_1.Query)(returns => employee_profile_1.EmployeeProfile, {
37
+ nullable: true,
38
+ description: "Fetches the caller's own profile. Null when the caller has written none, or when the account is not linked to an employee (myEmployees tells which)."
39
+ }),
40
+ tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
41
+ tslib_1.__metadata("design:type", Function),
42
+ tslib_1.__metadata("design:paramtypes", [Object]),
43
+ tslib_1.__metadata("design:returntype", Promise)
44
+ ], EmployeeProfileQuery.prototype, "myEmployeeProfile", null);
45
+ tslib_1.__decorate([
46
+ (0, type_graphql_1.Directive)('@privilege(category: "employee-profile", privilege: "query", domainOwnerGranted: true)'),
47
+ (0, type_graphql_1.Query)(returns => [employee_profile_type_1.EmployeeWithProfile], {
48
+ description: 'Fetches every active employee of the domain - not retired, not marked inactive - with their name, department, position, responsibility, hire day and profile; the profile is empty when they have written none.'
49
+ }),
50
+ tslib_1.__param(0, (0, type_graphql_1.Ctx)()),
51
+ tslib_1.__metadata("design:type", Function),
52
+ tslib_1.__metadata("design:paramtypes", [Object]),
53
+ tslib_1.__metadata("design:returntype", Promise)
54
+ ], EmployeeProfileQuery.prototype, "employeeProfiles", null);
55
+ exports.EmployeeProfileQuery = EmployeeProfileQuery = tslib_1.__decorate([
56
+ (0, type_graphql_1.Resolver)(employee_profile_1.EmployeeProfile)
57
+ ], EmployeeProfileQuery);
58
+ //# sourceMappingURL=employee-profile-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-profile-query.js","sourceRoot":"","sources":["../../../server/service/employee-profile/employee-profile-query.ts"],"names":[],"mappings":";;;;AAAA,+CAA8D;AAE9D,iDAAqD;AAErD,mDAA+C;AAC/C,+DAAwE;AACxE,yDAAoD;AACpD,qEAAyE;AACzE,mEAA6D;AAE7D;;;;GAIG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAMzB,AAAN,KAAK,CAAC,iBAAiB,CAAQ,OAAwB;QACrD,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACpC,MAAM,IAAI,GAAG,MAAM,IAAA,4BAAW,EAAC,OAAO,CAAC,CAAA;QACvC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAE7B,MAAM,QAAQ,GAAG,IAAA,+BAAc,EAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC9C,OAAO,MAAM,IAAA,qBAAa,EAAC,kCAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;IAClI,CAAC;IAOK,AAAN,KAAK,CAAC,gBAAgB,CAAQ,OAAwB;QACpD,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;QACpC,MAAM,SAAS,GAAG,MAAM,IAAA,qBAAa,EAAC,mBAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;QAC7H,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,kCAAe,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;QAExG,OAAO,IAAA,8CAAqB,EAAC,SAAS,EAAE,QAAQ,EAAE,IAAA,gCAAO,GAAE,CAAC,CAAA;IAC9D,CAAC;CACF,CAAA;AA3BY,oDAAoB;AAMzB;IALL,IAAA,wBAAS,EAAC,qFAAqF,CAAC;IAChG,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,kCAAe,EAAE;QACjC,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,sJAAsJ;KACpK,CAAC;IACuB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;6DAO7B;AAOK;IALL,IAAA,wBAAS,EAAC,wFAAwF,CAAC;IACnG,IAAA,oBAAK,EAAC,OAAO,CAAC,EAAE,CAAC,CAAC,2CAAmB,CAAC,EAAE;QACvC,WAAW,EACT,iNAAiN;KACpN,CAAC;IACsB,mBAAA,IAAA,kBAAG,GAAE,CAAA;;;;4DAM5B;+BA1BU,oBAAoB;IADhC,IAAA,uBAAQ,EAAC,kCAAe,CAAC;GACb,oBAAoB,CA2BhC","sourcesContent":["import { Ctx, Directive, Query, Resolver } from 'type-graphql'\n\nimport { getRepository } from '@things-factory/shell'\n\nimport { Employee } from '../employee/employee'\nimport { myEmployees, theOneEmployee } from '../employee/my-employee.js'\nimport { EmployeeProfile } from './employee-profile'\nimport { employeesWithProfiles, todayOf } from './employee-profile-rules'\nimport { EmployeeWithProfile } from './employee-profile-type'\n\n/*\n * Reading profiles (ADR-0169 decisions 3 · 4): one's own under `employee-self`, every active employee's under\n * `employee-profile` - the seats that attach profiles to quotations. Neither reads the employee record beyond the\n * basics a profile sheet shows.\n */\n@Resolver(EmployeeProfile)\nexport class EmployeeProfileQuery {\n @Directive('@privilege(category: \"employee-self\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => EmployeeProfile, {\n nullable: true,\n description: \"Fetches the caller's own profile. Null when the caller has written none, or when the account is not linked to an employee (myEmployees tells which).\"\n })\n async myEmployeeProfile(@Ctx() context: ResolverContext): Promise<EmployeeProfile | null> {\n const { domain, tx } = context.state\n const mine = await myEmployees(context)\n if (!mine.length) return null\n\n const employee = theOneEmployee(mine, context)\n return await getRepository(EmployeeProfile, tx).findOne({ where: { domain: { id: domain.id }, employee: { id: employee.id } } })\n }\n\n @Directive('@privilege(category: \"employee-profile\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => [EmployeeWithProfile], {\n description:\n 'Fetches every active employee of the domain - not retired, not marked inactive - with their name, department, position, responsibility, hire day and profile; the profile is empty when they have written none.'\n })\n async employeeProfiles(@Ctx() context: ResolverContext): Promise<EmployeeWithProfile[]> {\n const { domain, tx } = context.state\n const employees = await getRepository(Employee, tx).find({ where: { domain: { id: domain.id } }, relations: ['department'] })\n const profiles = await getRepository(EmployeeProfile, tx).find({ where: { domain: { id: domain.id } } })\n\n return employeesWithProfiles(employees, profiles, todayOf())\n }\n}\n"]}
@@ -0,0 +1,29 @@
1
+ export declare class EmployeeProfileEducation {
2
+ school?: string;
3
+ major?: string;
4
+ degree?: string;
5
+ startedOn?: string;
6
+ endedOn?: string;
7
+ }
8
+ export declare class EmployeeProfileCertificate {
9
+ name?: string;
10
+ issuer?: string;
11
+ acquiredOn?: string;
12
+ }
13
+ export declare class EmployeeProfileCareer {
14
+ company?: string;
15
+ department?: string;
16
+ position?: string;
17
+ startedOn?: string;
18
+ endedOn?: string;
19
+ duties?: string;
20
+ }
21
+ export declare class EmployeeProfileProject {
22
+ name?: string;
23
+ client?: string;
24
+ startedOn?: string;
25
+ endedOn?: string;
26
+ role?: string;
27
+ duties?: string;
28
+ technologies?: string;
29
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmployeeProfileProject = exports.EmployeeProfileCareer = exports.EmployeeProfileCertificate = exports.EmployeeProfileEducation = void 0;
4
+ const tslib_1 = require("tslib");
5
+ /*
6
+ * The rows of an employee profile (ADR-0169 decision 2). Each shape is read and written alike - the same fields come back
7
+ * as were saved - so it is one class, declared as an object type and, under another name, as its input.
8
+ */
9
+ const type_graphql_1 = require("type-graphql");
10
+ let EmployeeProfileEducation = class EmployeeProfileEducation {
11
+ };
12
+ exports.EmployeeProfileEducation = EmployeeProfileEducation;
13
+ tslib_1.__decorate([
14
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The school.' }),
15
+ tslib_1.__metadata("design:type", String)
16
+ ], EmployeeProfileEducation.prototype, "school", void 0);
17
+ tslib_1.__decorate([
18
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The major.' }),
19
+ tslib_1.__metadata("design:type", String)
20
+ ], EmployeeProfileEducation.prototype, "major", void 0);
21
+ tslib_1.__decorate([
22
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The degree or the stage finished - e.g. bachelor, master, high school.' }),
23
+ tslib_1.__metadata("design:type", String)
24
+ ], EmployeeProfileEducation.prototype, "degree", void 0);
25
+ tslib_1.__decorate([
26
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When it started, YYYY-MM.' }),
27
+ tslib_1.__metadata("design:type", String)
28
+ ], EmployeeProfileEducation.prototype, "startedOn", void 0);
29
+ tslib_1.__decorate([
30
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When it ended, YYYY-MM - empty while still at it.' }),
31
+ tslib_1.__metadata("design:type", String)
32
+ ], EmployeeProfileEducation.prototype, "endedOn", void 0);
33
+ exports.EmployeeProfileEducation = EmployeeProfileEducation = tslib_1.__decorate([
34
+ (0, type_graphql_1.ObjectType)('EmployeeProfileEducation', { description: 'A school the employee went to.' }),
35
+ (0, type_graphql_1.InputType)('EmployeeProfileEducationInput', { description: 'A school the employee went to.' })
36
+ ], EmployeeProfileEducation);
37
+ let EmployeeProfileCertificate = class EmployeeProfileCertificate {
38
+ };
39
+ exports.EmployeeProfileCertificate = EmployeeProfileCertificate;
40
+ tslib_1.__decorate([
41
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The name of the certificate.' }),
42
+ tslib_1.__metadata("design:type", String)
43
+ ], EmployeeProfileCertificate.prototype, "name", void 0);
44
+ tslib_1.__decorate([
45
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Who issued it.' }),
46
+ tslib_1.__metadata("design:type", String)
47
+ ], EmployeeProfileCertificate.prototype, "issuer", void 0);
48
+ tslib_1.__decorate([
49
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The day it was acquired, YYYY-MM-DD.' }),
50
+ tslib_1.__metadata("design:type", String)
51
+ ], EmployeeProfileCertificate.prototype, "acquiredOn", void 0);
52
+ exports.EmployeeProfileCertificate = EmployeeProfileCertificate = tslib_1.__decorate([
53
+ (0, type_graphql_1.ObjectType)('EmployeeProfileCertificate', { description: 'A certificate or licence the employee holds.' }),
54
+ (0, type_graphql_1.InputType)('EmployeeProfileCertificateInput', { description: 'A certificate or licence the employee holds.' })
55
+ ], EmployeeProfileCertificate);
56
+ let EmployeeProfileCareer = class EmployeeProfileCareer {
57
+ };
58
+ exports.EmployeeProfileCareer = EmployeeProfileCareer;
59
+ tslib_1.__decorate([
60
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The company.' }),
61
+ tslib_1.__metadata("design:type", String)
62
+ ], EmployeeProfileCareer.prototype, "company", void 0);
63
+ tslib_1.__decorate([
64
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The department there.' }),
65
+ tslib_1.__metadata("design:type", String)
66
+ ], EmployeeProfileCareer.prototype, "department", void 0);
67
+ tslib_1.__decorate([
68
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The position there.' }),
69
+ tslib_1.__metadata("design:type", String)
70
+ ], EmployeeProfileCareer.prototype, "position", void 0);
71
+ tslib_1.__decorate([
72
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When it started, YYYY-MM.' }),
73
+ tslib_1.__metadata("design:type", String)
74
+ ], EmployeeProfileCareer.prototype, "startedOn", void 0);
75
+ tslib_1.__decorate([
76
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When it ended, YYYY-MM.' }),
77
+ tslib_1.__metadata("design:type", String)
78
+ ], EmployeeProfileCareer.prototype, "endedOn", void 0);
79
+ tslib_1.__decorate([
80
+ (0, type_graphql_1.Field)({ nullable: true, description: 'What the employee did there.' }),
81
+ tslib_1.__metadata("design:type", String)
82
+ ], EmployeeProfileCareer.prototype, "duties", void 0);
83
+ exports.EmployeeProfileCareer = EmployeeProfileCareer = tslib_1.__decorate([
84
+ (0, type_graphql_1.ObjectType)('EmployeeProfileCareer', { description: 'A job the employee held before - at another company.' }),
85
+ (0, type_graphql_1.InputType)('EmployeeProfileCareerInput', { description: 'A job the employee held before - at another company.' })
86
+ ], EmployeeProfileCareer);
87
+ let EmployeeProfileProject = class EmployeeProfileProject {
88
+ };
89
+ exports.EmployeeProfileProject = EmployeeProfileProject;
90
+ tslib_1.__decorate([
91
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The name of the project.' }),
92
+ tslib_1.__metadata("design:type", String)
93
+ ], EmployeeProfileProject.prototype, "name", void 0);
94
+ tslib_1.__decorate([
95
+ (0, type_graphql_1.Field)({ nullable: true, description: 'Who ordered it - the client.' }),
96
+ tslib_1.__metadata("design:type", String)
97
+ ], EmployeeProfileProject.prototype, "client", void 0);
98
+ tslib_1.__decorate([
99
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When the employee joined it, YYYY-MM.' }),
100
+ tslib_1.__metadata("design:type", String)
101
+ ], EmployeeProfileProject.prototype, "startedOn", void 0);
102
+ tslib_1.__decorate([
103
+ (0, type_graphql_1.Field)({ nullable: true, description: 'When the employee left it, YYYY-MM - empty while still on it.' }),
104
+ tslib_1.__metadata("design:type", String)
105
+ ], EmployeeProfileProject.prototype, "endedOn", void 0);
106
+ tslib_1.__decorate([
107
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The role on it - e.g. PM, developer.' }),
108
+ tslib_1.__metadata("design:type", String)
109
+ ], EmployeeProfileProject.prototype, "role", void 0);
110
+ tslib_1.__decorate([
111
+ (0, type_graphql_1.Field)({ nullable: true, description: 'What the employee did on it.' }),
112
+ tslib_1.__metadata("design:type", String)
113
+ ], EmployeeProfileProject.prototype, "duties", void 0);
114
+ tslib_1.__decorate([
115
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The technologies used, as written.' }),
116
+ tslib_1.__metadata("design:type", String)
117
+ ], EmployeeProfileProject.prototype, "technologies", void 0);
118
+ exports.EmployeeProfileProject = EmployeeProfileProject = tslib_1.__decorate([
119
+ (0, type_graphql_1.ObjectType)('EmployeeProfileProject', { description: 'A project the employee worked on.' }),
120
+ (0, type_graphql_1.InputType)('EmployeeProfileProjectInput', { description: 'A project the employee worked on.' })
121
+ ], EmployeeProfileProject);
122
+ //# sourceMappingURL=employee-profile-rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-profile-rows.js","sourceRoot":"","sources":["../../../server/service/employee-profile/employee-profile-rows.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The rows of an employee profile (ADR-0169 decision 2). Each shape is read and written alike - the same fields come back\n * as were saved - so it is one class, declared as an object type and, under another name, as its input.\n */\nimport { Field, InputType, ObjectType } from 'type-graphql'\n\n@ObjectType('EmployeeProfileEducation', { description: 'A school the employee went to.' })\n@InputType('EmployeeProfileEducationInput', { description: 'A school the employee went to.' })\nexport class EmployeeProfileEducation {\n @Field({ nullable: true, description: 'The school.' })\n school?: string\n\n @Field({ nullable: true, description: 'The major.' })\n major?: string\n\n @Field({ nullable: true, description: 'The degree or the stage finished - e.g. bachelor, master, high school.' })\n degree?: string\n\n @Field({ nullable: true, description: 'When it started, YYYY-MM.' })\n startedOn?: string\n\n @Field({ nullable: true, description: 'When it ended, YYYY-MM - empty while still at it.' })\n endedOn?: string\n}\n\n@ObjectType('EmployeeProfileCertificate', { description: 'A certificate or licence the employee holds.' })\n@InputType('EmployeeProfileCertificateInput', { description: 'A certificate or licence the employee holds.' })\nexport class EmployeeProfileCertificate {\n @Field({ nullable: true, description: 'The name of the certificate.' })\n name?: string\n\n @Field({ nullable: true, description: 'Who issued it.' })\n issuer?: string\n\n @Field({ nullable: true, description: 'The day it was acquired, YYYY-MM-DD.' })\n acquiredOn?: string\n}\n\n@ObjectType('EmployeeProfileCareer', { description: 'A job the employee held before - at another company.' })\n@InputType('EmployeeProfileCareerInput', { description: 'A job the employee held before - at another company.' })\nexport class EmployeeProfileCareer {\n @Field({ nullable: true, description: 'The company.' })\n company?: string\n\n @Field({ nullable: true, description: 'The department there.' })\n department?: string\n\n @Field({ nullable: true, description: 'The position there.' })\n position?: string\n\n @Field({ nullable: true, description: 'When it started, YYYY-MM.' })\n startedOn?: string\n\n @Field({ nullable: true, description: 'When it ended, YYYY-MM.' })\n endedOn?: string\n\n @Field({ nullable: true, description: 'What the employee did there.' })\n duties?: string\n}\n\n@ObjectType('EmployeeProfileProject', { description: 'A project the employee worked on.' })\n@InputType('EmployeeProfileProjectInput', { description: 'A project the employee worked on.' })\nexport class EmployeeProfileProject {\n @Field({ nullable: true, description: 'The name of the project.' })\n name?: string\n\n @Field({ nullable: true, description: 'Who ordered it - the client.' })\n client?: string\n\n @Field({ nullable: true, description: 'When the employee joined it, YYYY-MM.' })\n startedOn?: string\n\n @Field({ nullable: true, description: 'When the employee left it, YYYY-MM - empty while still on it.' })\n endedOn?: string\n\n @Field({ nullable: true, description: 'The role on it - e.g. PM, developer.' })\n role?: string\n\n @Field({ nullable: true, description: 'What the employee did on it.' })\n duties?: string\n\n @Field({ nullable: true, description: 'The technologies used, as written.' })\n technologies?: string\n}\n"]}
@@ -0,0 +1,55 @@
1
+ type Row = Record<string, unknown>;
2
+ export type ProfileDocument = {
3
+ summary: string | null;
4
+ skills: string[];
5
+ educations: Row[];
6
+ certificates: Row[];
7
+ careers: Row[];
8
+ projects: Row[];
9
+ };
10
+ /** The fields each kind of row keeps; anything else a caller sends is not stored. */
11
+ export declare const PROFILE_ROW_FIELDS: {
12
+ readonly educations: readonly ["school", "major", "degree", "startedOn", "endedOn"];
13
+ readonly certificates: readonly ["name", "issuer", "acquiredOn"];
14
+ readonly careers: readonly ["company", "department", "position", "startedOn", "endedOn", "duties"];
15
+ readonly projects: readonly ["name", "client", "startedOn", "endedOn", "role", "duties", "technologies"];
16
+ };
17
+ /**
18
+ * The profile as it is saved - whole, as the screen sent it (ADR-0169 decision 2). Blank rows the screen added and did
19
+ * not fill go, and a skill written twice is kept once.
20
+ */
21
+ export declare function profileDocumentOf(input: any): ProfileDocument;
22
+ export type ProfileEmployee = {
23
+ id: string;
24
+ controlNo?: string;
25
+ name?: string;
26
+ active?: boolean | null;
27
+ retiredOn?: string | null;
28
+ jobPosition?: string;
29
+ jobResponsibility?: string;
30
+ hiredOn?: string;
31
+ department?: {
32
+ name?: string;
33
+ } | null;
34
+ };
35
+ /** Still working here: not marked inactive, and no retire day that has come. `today` is YYYY-MM-DD. */
36
+ export declare function isActiveEmployee(employee: ProfileEmployee, today: string): boolean;
37
+ /**
38
+ * Every active employee with their profile, by name (ADR-0169 decision 4) - an employee who has written none is listed
39
+ * with an empty one, so the list says who has not written it rather than leaving them out.
40
+ */
41
+ export declare function employeesWithProfiles<P extends {
42
+ employeeId?: string;
43
+ }>(employees: ProfileEmployee[], profiles: P[], today: string): {
44
+ employeeId: string;
45
+ controlNo: string;
46
+ name: string;
47
+ departmentName: string;
48
+ jobPosition: string;
49
+ jobResponsibility: string;
50
+ hiredOn: string;
51
+ profile: P;
52
+ }[];
53
+ /** Today in the server's calendar, YYYY-MM-DD - the form `retiredOn` is kept in. */
54
+ export declare function todayOf(now?: Date): string;
55
+ export {};
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /*
3
+ * The judgements of the profile's doors (ADR-0169) - pure, apart from the store, so the tests read them without the
4
+ * entities (the employee record pulls in contact, which reads the configuration when it is loaded).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PROFILE_ROW_FIELDS = void 0;
8
+ exports.profileDocumentOf = profileDocumentOf;
9
+ exports.isActiveEmployee = isActiveEmployee;
10
+ exports.employeesWithProfiles = employeesWithProfiles;
11
+ exports.todayOf = todayOf;
12
+ /** The fields each kind of row keeps; anything else a caller sends is not stored. */
13
+ exports.PROFILE_ROW_FIELDS = {
14
+ educations: ['school', 'major', 'degree', 'startedOn', 'endedOn'],
15
+ certificates: ['name', 'issuer', 'acquiredOn'],
16
+ careers: ['company', 'department', 'position', 'startedOn', 'endedOn', 'duties'],
17
+ projects: ['name', 'client', 'startedOn', 'endedOn', 'role', 'duties', 'technologies']
18
+ };
19
+ const text = (value) => (typeof value === 'string' ? value.trim() : '');
20
+ /** A row as kept: its own fields trimmed, empty ones left out. A row with nothing in it is no row. */
21
+ function rowsOf(rows, fields) {
22
+ if (!Array.isArray(rows))
23
+ return [];
24
+ return rows.flatMap(row => {
25
+ const kept = {};
26
+ for (const field of fields) {
27
+ const value = text(row?.[field]);
28
+ if (value)
29
+ kept[field] = value;
30
+ }
31
+ return Object.keys(kept).length ? [kept] : [];
32
+ });
33
+ }
34
+ /**
35
+ * The profile as it is saved - whole, as the screen sent it (ADR-0169 decision 2). Blank rows the screen added and did
36
+ * not fill go, and a skill written twice is kept once.
37
+ */
38
+ function profileDocumentOf(input) {
39
+ const skills = [...new Set((Array.isArray(input?.skills) ? input.skills : []).map(text).filter(Boolean))];
40
+ return {
41
+ summary: text(input?.summary) || null,
42
+ skills,
43
+ educations: rowsOf(input?.educations, exports.PROFILE_ROW_FIELDS.educations),
44
+ certificates: rowsOf(input?.certificates, exports.PROFILE_ROW_FIELDS.certificates),
45
+ careers: rowsOf(input?.careers, exports.PROFILE_ROW_FIELDS.careers),
46
+ projects: rowsOf(input?.projects, exports.PROFILE_ROW_FIELDS.projects)
47
+ };
48
+ }
49
+ /** Still working here: not marked inactive, and no retire day that has come. `today` is YYYY-MM-DD. */
50
+ function isActiveEmployee(employee, today) {
51
+ if (employee.active === false)
52
+ return false;
53
+ return !employee.retiredOn || employee.retiredOn > today;
54
+ }
55
+ /**
56
+ * Every active employee with their profile, by name (ADR-0169 decision 4) - an employee who has written none is listed
57
+ * with an empty one, so the list says who has not written it rather than leaving them out.
58
+ */
59
+ function employeesWithProfiles(employees, profiles, today) {
60
+ const byEmployee = new Map(profiles.map(profile => [profile.employeeId, profile]));
61
+ return employees
62
+ .filter(employee => isActiveEmployee(employee, today))
63
+ .map(employee => ({
64
+ employeeId: employee.id,
65
+ controlNo: employee.controlNo,
66
+ name: employee.name,
67
+ departmentName: employee.department?.name,
68
+ jobPosition: employee.jobPosition,
69
+ jobResponsibility: employee.jobResponsibility,
70
+ hiredOn: employee.hiredOn,
71
+ profile: byEmployee.get(employee.id) ?? null
72
+ }))
73
+ .sort((a, b) => (a.name ?? '').localeCompare(b.name ?? '', 'ko') || (a.controlNo ?? '').localeCompare(b.controlNo ?? ''));
74
+ }
75
+ /** Today in the server's calendar, YYYY-MM-DD - the form `retiredOn` is kept in. */
76
+ function todayOf(now = new Date()) {
77
+ const pad = (n) => String(n).padStart(2, '0');
78
+ return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`;
79
+ }
80
+ //# sourceMappingURL=employee-profile-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-profile-rules.js","sourceRoot":"","sources":["../../../server/service/employee-profile/employee-profile-rules.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The judgements of the profile's doors (ADR-0169) - pure, apart from the store, so the tests read them without the\n * entities (the employee record pulls in contact, which reads the configuration when it is loaded).\n */\n\ntype Row = Record<string, unknown>\n\nexport type ProfileDocument = {\n summary: string | null\n skills: string[]\n educations: Row[]\n certificates: Row[]\n careers: Row[]\n projects: Row[]\n}\n\n/** The fields each kind of row keeps; anything else a caller sends is not stored. */\nexport const PROFILE_ROW_FIELDS = {\n educations: ['school', 'major', 'degree', 'startedOn', 'endedOn'],\n certificates: ['name', 'issuer', 'acquiredOn'],\n careers: ['company', 'department', 'position', 'startedOn', 'endedOn', 'duties'],\n projects: ['name', 'client', 'startedOn', 'endedOn', 'role', 'duties', 'technologies']\n} as const\n\nconst text = (value: unknown): string => (typeof value === 'string' ? value.trim() : '')\n\n/** A row as kept: its own fields trimmed, empty ones left out. A row with nothing in it is no row. */\nfunction rowsOf(rows: unknown, fields: readonly string[]): Row[] {\n if (!Array.isArray(rows)) return []\n return rows.flatMap(row => {\n const kept: Row = {}\n for (const field of fields) {\n const value = text((row as Row | null)?.[field])\n if (value) kept[field] = value\n }\n return Object.keys(kept).length ? [kept] : []\n })\n}\n\n/**\n * The profile as it is saved - whole, as the screen sent it (ADR-0169 decision 2). Blank rows the screen added and did\n * not fill go, and a skill written twice is kept once.\n */\nexport function profileDocumentOf(input: any): ProfileDocument {\n const skills = [...new Set((Array.isArray(input?.skills) ? input.skills : []).map(text).filter(Boolean))] as string[]\n return {\n summary: text(input?.summary) || null,\n skills,\n educations: rowsOf(input?.educations, PROFILE_ROW_FIELDS.educations),\n certificates: rowsOf(input?.certificates, PROFILE_ROW_FIELDS.certificates),\n careers: rowsOf(input?.careers, PROFILE_ROW_FIELDS.careers),\n projects: rowsOf(input?.projects, PROFILE_ROW_FIELDS.projects)\n }\n}\n\nexport type ProfileEmployee = {\n id: string\n controlNo?: string\n name?: string\n active?: boolean | null\n retiredOn?: string | null\n jobPosition?: string\n jobResponsibility?: string\n hiredOn?: string\n department?: { name?: string } | null\n}\n\n/** Still working here: not marked inactive, and no retire day that has come. `today` is YYYY-MM-DD. */\nexport function isActiveEmployee(employee: ProfileEmployee, today: string): boolean {\n if (employee.active === false) return false\n return !employee.retiredOn || employee.retiredOn > today\n}\n\n/**\n * Every active employee with their profile, by name (ADR-0169 decision 4) - an employee who has written none is listed\n * with an empty one, so the list says who has not written it rather than leaving them out.\n */\nexport function employeesWithProfiles<P extends { employeeId?: string }>(employees: ProfileEmployee[], profiles: P[], today: string) {\n const byEmployee = new Map(profiles.map(profile => [profile.employeeId, profile]))\n return employees\n .filter(employee => isActiveEmployee(employee, today))\n .map(employee => ({\n employeeId: employee.id,\n controlNo: employee.controlNo,\n name: employee.name,\n departmentName: employee.department?.name,\n jobPosition: employee.jobPosition,\n jobResponsibility: employee.jobResponsibility,\n hiredOn: employee.hiredOn,\n profile: byEmployee.get(employee.id) ?? null\n }))\n .sort((a, b) => (a.name ?? '').localeCompare(b.name ?? '', 'ko') || (a.controlNo ?? '').localeCompare(b.controlNo ?? ''))\n}\n\n/** Today in the server's calendar, YYYY-MM-DD - the form `retiredOn` is kept in. */\nexport function todayOf(now = new Date()): string {\n const pad = (n: number) => String(n).padStart(2, '0')\n return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { EmployeeProfile } from './employee-profile';
2
+ import { EmployeeProfileCareer, EmployeeProfileCertificate, EmployeeProfileEducation, EmployeeProfileProject } from './employee-profile-rows';
3
+ export declare class EmployeeProfileInput {
4
+ summary?: string;
5
+ skills?: string[];
6
+ educations?: EmployeeProfileEducation[];
7
+ certificates?: EmployeeProfileCertificate[];
8
+ careers?: EmployeeProfileCareer[];
9
+ projects?: EmployeeProfileProject[];
10
+ }
11
+ /**
12
+ * One active employee with their profile, for the list a quotation's profiles are taken from (ADR-0169 decisions 1 · 4).
13
+ * The basics are read from the employee record and nothing else of it - no contact, address, birthday, account or pay.
14
+ */
15
+ export declare class EmployeeWithProfile {
16
+ employeeId: string;
17
+ controlNo?: string;
18
+ name?: string;
19
+ departmentName?: string;
20
+ jobPosition?: string;
21
+ jobResponsibility?: string;
22
+ hiredOn?: string;
23
+ profile?: EmployeeProfile;
24
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmployeeWithProfile = exports.EmployeeProfileInput = void 0;
4
+ const tslib_1 = require("tslib");
5
+ /* The documents the profile's doors take and give (ADR-0169 decisions 2 · 4). */
6
+ const type_graphql_1 = require("type-graphql");
7
+ const employee_profile_1 = require("./employee-profile");
8
+ const employee_profile_rows_1 = require("./employee-profile-rows");
9
+ let EmployeeProfileInput = class EmployeeProfileInput {
10
+ };
11
+ exports.EmployeeProfileInput = EmployeeProfileInput;
12
+ tslib_1.__decorate([
13
+ (0, type_graphql_1.Field)({ nullable: true, description: 'A few lines about the employee.' }),
14
+ tslib_1.__metadata("design:type", String)
15
+ ], EmployeeProfileInput.prototype, "summary", void 0);
16
+ tslib_1.__decorate([
17
+ (0, type_graphql_1.Field)(type => [String], { nullable: true, description: 'The skills, each a word or two.' }),
18
+ tslib_1.__metadata("design:type", Array)
19
+ ], EmployeeProfileInput.prototype, "skills", void 0);
20
+ tslib_1.__decorate([
21
+ (0, type_graphql_1.Field)(type => [employee_profile_rows_1.EmployeeProfileEducation], { nullable: true, description: 'The schools.' }),
22
+ tslib_1.__metadata("design:type", Array)
23
+ ], EmployeeProfileInput.prototype, "educations", void 0);
24
+ tslib_1.__decorate([
25
+ (0, type_graphql_1.Field)(type => [employee_profile_rows_1.EmployeeProfileCertificate], { nullable: true, description: 'The certificates and licences.' }),
26
+ tslib_1.__metadata("design:type", Array)
27
+ ], EmployeeProfileInput.prototype, "certificates", void 0);
28
+ tslib_1.__decorate([
29
+ (0, type_graphql_1.Field)(type => [employee_profile_rows_1.EmployeeProfileCareer], { nullable: true, description: 'The jobs held before, at other companies.' }),
30
+ tslib_1.__metadata("design:type", Array)
31
+ ], EmployeeProfileInput.prototype, "careers", void 0);
32
+ tslib_1.__decorate([
33
+ (0, type_graphql_1.Field)(type => [employee_profile_rows_1.EmployeeProfileProject], { nullable: true, description: 'The projects worked on.' }),
34
+ tslib_1.__metadata("design:type", Array)
35
+ ], EmployeeProfileInput.prototype, "projects", void 0);
36
+ exports.EmployeeProfileInput = EmployeeProfileInput = tslib_1.__decorate([
37
+ (0, type_graphql_1.InputType)({ description: "The caller's own profile, whole - what is left out is emptied (ADR-0169 decision 2)." })
38
+ ], EmployeeProfileInput);
39
+ /**
40
+ * One active employee with their profile, for the list a quotation's profiles are taken from (ADR-0169 decisions 1 · 4).
41
+ * The basics are read from the employee record and nothing else of it - no contact, address, birthday, account or pay.
42
+ */
43
+ let EmployeeWithProfile = class EmployeeWithProfile {
44
+ };
45
+ exports.EmployeeWithProfile = EmployeeWithProfile;
46
+ tslib_1.__decorate([
47
+ (0, type_graphql_1.Field)({ description: 'The employee id.' }),
48
+ tslib_1.__metadata("design:type", String)
49
+ ], EmployeeWithProfile.prototype, "employeeId", void 0);
50
+ tslib_1.__decorate([
51
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The employee control number.' }),
52
+ tslib_1.__metadata("design:type", String)
53
+ ], EmployeeWithProfile.prototype, "controlNo", void 0);
54
+ tslib_1.__decorate([
55
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The name.' }),
56
+ tslib_1.__metadata("design:type", String)
57
+ ], EmployeeWithProfile.prototype, "name", void 0);
58
+ tslib_1.__decorate([
59
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The name of the department.' }),
60
+ tslib_1.__metadata("design:type", String)
61
+ ], EmployeeWithProfile.prototype, "departmentName", void 0);
62
+ tslib_1.__decorate([
63
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The position (rank).' }),
64
+ tslib_1.__metadata("design:type", String)
65
+ ], EmployeeWithProfile.prototype, "jobPosition", void 0);
66
+ tslib_1.__decorate([
67
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The responsibility (title).' }),
68
+ tslib_1.__metadata("design:type", String)
69
+ ], EmployeeWithProfile.prototype, "jobResponsibility", void 0);
70
+ tslib_1.__decorate([
71
+ (0, type_graphql_1.Field)({ nullable: true, description: 'The hire day, YYYY-MM-DD.' }),
72
+ tslib_1.__metadata("design:type", String)
73
+ ], EmployeeWithProfile.prototype, "hiredOn", void 0);
74
+ tslib_1.__decorate([
75
+ (0, type_graphql_1.Field)(type => employee_profile_1.EmployeeProfile, { nullable: true, description: 'The profile - empty when the employee has written none.' }),
76
+ tslib_1.__metadata("design:type", employee_profile_1.EmployeeProfile)
77
+ ], EmployeeWithProfile.prototype, "profile", void 0);
78
+ exports.EmployeeWithProfile = EmployeeWithProfile = tslib_1.__decorate([
79
+ (0, type_graphql_1.ObjectType)({ description: 'An active employee of the domain with their profile - empty when they have written none.' })
80
+ ], EmployeeWithProfile);
81
+ //# sourceMappingURL=employee-profile-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"employee-profile-type.js","sourceRoot":"","sources":["../../../server/service/employee-profile/employee-profile-type.ts"],"names":[],"mappings":";;;;AAAA,iFAAiF;AACjF,+CAA2D;AAE3D,yDAAoD;AACpD,mEAA6I;AAGtI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;CAkBhC,CAAA;AAlBY,oDAAoB;AAE/B;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC;;qDAC1D;AAGhB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC;;oDAC3E;AAGjB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,gDAAwB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;;wDACpD;AAGvC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,kDAA0B,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,gCAAgC,EAAE,CAAC;;0DACpE;AAG3C;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,6CAAqB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2CAA2C,EAAE,CAAC;;qDACpF;AAGjC;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,8CAAsB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;;sDACjE;+BAjBxB,oBAAoB;IADhC,IAAA,wBAAS,EAAC,EAAE,WAAW,EAAE,sFAAsF,EAAE,CAAC;GACtG,oBAAoB,CAkBhC;AAED;;;GAGG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;CAwB/B,CAAA;AAxBY,kDAAmB;AAE9B;IADC,IAAA,oBAAK,EAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;;uDACzB;AAGlB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,8BAA8B,EAAE,CAAC;;sDACrD;AAGlB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;;iDACvC;AAGb;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;;2DAC/C;AAGvB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;;wDAC3C;AAGpB;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,6BAA6B,EAAE,CAAC;;8DAC5C;AAG1B;IADC,IAAA,oBAAK,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;;oDACpD;AAGhB;IADC,IAAA,oBAAK,EAAC,IAAI,CAAC,EAAE,CAAC,kCAAe,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,yDAAyD,EAAE,CAAC;sCACjH,kCAAe;oDAAA;8BAvBd,mBAAmB;IAD/B,IAAA,yBAAU,EAAC,EAAE,WAAW,EAAE,0FAA0F,EAAE,CAAC;GAC3G,mBAAmB,CAwB/B","sourcesContent":["/* The documents the profile's doors take and give (ADR-0169 decisions 2 · 4). */\nimport { Field, InputType, ObjectType } from 'type-graphql'\n\nimport { EmployeeProfile } from './employee-profile'\nimport { EmployeeProfileCareer, EmployeeProfileCertificate, EmployeeProfileEducation, EmployeeProfileProject } from './employee-profile-rows'\n\n@InputType({ description: \"The caller's own profile, whole - what is left out is emptied (ADR-0169 decision 2).\" })\nexport class EmployeeProfileInput {\n @Field({ nullable: true, description: 'A few lines about the employee.' })\n summary?: string\n\n @Field(type => [String], { nullable: true, description: 'The skills, each a word or two.' })\n skills?: string[]\n\n @Field(type => [EmployeeProfileEducation], { nullable: true, description: 'The schools.' })\n educations?: EmployeeProfileEducation[]\n\n @Field(type => [EmployeeProfileCertificate], { nullable: true, description: 'The certificates and licences.' })\n certificates?: EmployeeProfileCertificate[]\n\n @Field(type => [EmployeeProfileCareer], { nullable: true, description: 'The jobs held before, at other companies.' })\n careers?: EmployeeProfileCareer[]\n\n @Field(type => [EmployeeProfileProject], { nullable: true, description: 'The projects worked on.' })\n projects?: EmployeeProfileProject[]\n}\n\n/**\n * One active employee with their profile, for the list a quotation's profiles are taken from (ADR-0169 decisions 1 · 4).\n * The basics are read from the employee record and nothing else of it - no contact, address, birthday, account or pay.\n */\n@ObjectType({ description: 'An active employee of the domain with their profile - empty when they have written none.' })\nexport class EmployeeWithProfile {\n @Field({ description: 'The employee id.' })\n employeeId: string\n\n @Field({ nullable: true, description: 'The employee control number.' })\n controlNo?: string\n\n @Field({ nullable: true, description: 'The name.' })\n name?: string\n\n @Field({ nullable: true, description: 'The name of the department.' })\n departmentName?: string\n\n @Field({ nullable: true, description: 'The position (rank).' })\n jobPosition?: string\n\n @Field({ nullable: true, description: 'The responsibility (title).' })\n jobResponsibility?: string\n\n @Field({ nullable: true, description: 'The hire day, YYYY-MM-DD.' })\n hiredOn?: string\n\n @Field(type => EmployeeProfile, { nullable: true, description: 'The profile - empty when the employee has written none.' })\n profile?: EmployeeProfile\n}\n"]}