@acorex-platform/module-software-management-client 0.0.46

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 (23) hide show
  1. package/fesm2022/acorex-platform-module-software-management-client-accept-software-suggestion.command-DVcM5TTv.mjs +83 -0
  2. package/fesm2022/acorex-platform-module-software-management-client-accept-software-suggestion.command-DVcM5TTv.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-software-management-client-complete-software-phase.activity-C56HhK20.mjs +182 -0
  4. package/fesm2022/acorex-platform-module-software-management-client-complete-software-phase.activity-C56HhK20.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-software-management-client-contracts.mjs +1196 -0
  6. package/fesm2022/acorex-platform-module-software-management-client-contracts.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-module-software-management-client-discovery-kickoff.commands-gB0_htfF.mjs +162 -0
  8. package/fesm2022/acorex-platform-module-software-management-client-discovery-kickoff.commands-gB0_htfF.mjs.map +1 -0
  9. package/fesm2022/acorex-platform-module-software-management-client-discovery-report.commands-D2ricLpq.mjs +278 -0
  10. package/fesm2022/acorex-platform-module-software-management-client-discovery-report.commands-D2ricLpq.mjs.map +1 -0
  11. package/fesm2022/acorex-platform-module-software-management-client-introduction-exit-message.util-DShFM8MY.mjs +71 -0
  12. package/fesm2022/acorex-platform-module-software-management-client-introduction-exit-message.util-DShFM8MY.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-module-software-management-client-introduction-task.activities-BOsJbeJe.mjs +158 -0
  14. package/fesm2022/acorex-platform-module-software-management-client-introduction-task.activities-BOsJbeJe.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-module-software-management-client-software-command.util-BsoKQCX5.mjs +9 -0
  16. package/fesm2022/acorex-platform-module-software-management-client-software-command.util-BsoKQCX5.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-module-software-management-client-start-software-definition-flow.command-B0YCgv2V.mjs +124 -0
  18. package/fesm2022/acorex-platform-module-software-management-client-start-software-definition-flow.command-B0YCgv2V.mjs.map +1 -0
  19. package/fesm2022/acorex-platform-module-software-management-client.mjs +260 -0
  20. package/fesm2022/acorex-platform-module-software-management-client.mjs.map +1 -0
  21. package/package.json +28 -0
  22. package/types/acorex-platform-module-software-management-client-contracts.d.ts +547 -0
  23. package/types/acorex-platform-module-software-management-client.d.ts +9 -0
@@ -0,0 +1,83 @@
1
+ import { AXToastService } from '@acorex/components/toast';
2
+ import { AXTranslationService } from '@acorex/core/translation';
3
+ import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
4
+ import { resolveEntityActionRef } from '@acorex-platform/framework-shared/runtime';
5
+ import { RootConfig } from '@acorex-platform/module-software-management-client/contracts';
6
+ import * as i0 from '@angular/core';
7
+ import { inject, Injectable } from '@angular/core';
8
+ import { r as resolveSoftwareText } from './acorex-platform-module-software-management-client-software-command.util-BsoKQCX5.mjs';
9
+
10
+ //#region ---- Imports ----
11
+ //#endregion
12
+ class AcceptSoftwareSuggestionCommand {
13
+ constructor() {
14
+ //#region ---- Services & Dependencies ----
15
+ this.entityService = inject(AXPEntityService);
16
+ this.toastService = inject(AXToastService);
17
+ this.translationService = inject(AXTranslationService);
18
+ }
19
+ //#endregion
20
+ //#region ---- Command Implementation ----
21
+ async execute(input) {
22
+ const resolved = resolveEntityActionRef(input);
23
+ const refType = resolveSoftwareText(resolved?.refType);
24
+ const refId = resolveSoftwareText(resolved?.refId);
25
+ if (!refType || !refId) {
26
+ return {
27
+ success: false,
28
+ message: {
29
+ text: await this.translationService.translateAsync('@software-management:messages.accept-suggestion.ref-required'),
30
+ },
31
+ };
32
+ }
33
+ const [moduleName, entityName] = refType.split('.');
34
+ if (moduleName !== RootConfig.module.name || !entityName) {
35
+ return {
36
+ success: false,
37
+ message: {
38
+ text: await this.translationService.translateAsync('@software-management:messages.accept-suggestion.unsupported'),
39
+ },
40
+ };
41
+ }
42
+ const record = (await this.entityService
43
+ .withEntity(moduleName, entityName)
44
+ .data()
45
+ .byKey(refId));
46
+ if (!record) {
47
+ return { success: false, message: { text: 'Record not found' } };
48
+ }
49
+ if (record.origin !== 'suggestion') {
50
+ this.toastService.show({
51
+ color: 'warning',
52
+ title: await this.translationService.translateAsync('@general:messages.generic.warning.title'),
53
+ content: await this.translationService.translateAsync('@software-management:messages.accept-suggestion.not-suggestion'),
54
+ closeButton: true,
55
+ timeOut: 5000,
56
+ });
57
+ return { success: false };
58
+ }
59
+ await this.entityService.withEntity(moduleName, entityName).data().update(refId, {
60
+ origin: 'approved-fact',
61
+ acceptedAt: new Date().toISOString(),
62
+ needsReview: false,
63
+ reviewReason: '',
64
+ });
65
+ this.toastService.show({
66
+ color: 'success',
67
+ title: await this.translationService.translateAsync('@general:messages.generic.success.title'),
68
+ content: await this.translationService.translateAsync('@software-management:messages.accept-suggestion.accepted'),
69
+ closeButton: true,
70
+ timeOut: 4000,
71
+ });
72
+ return { success: true, kind: 'object', data: undefined };
73
+ }
74
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AcceptSoftwareSuggestionCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
75
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AcceptSoftwareSuggestionCommand, providedIn: 'root' }); }
76
+ }
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AcceptSoftwareSuggestionCommand, decorators: [{
78
+ type: Injectable,
79
+ args: [{ providedIn: 'root' }]
80
+ }] });
81
+
82
+ export { AcceptSoftwareSuggestionCommand };
83
+ //# sourceMappingURL=acorex-platform-module-software-management-client-accept-software-suggestion.command-DVcM5TTv.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-software-management-client-accept-software-suggestion.command-DVcM5TTv.mjs","sources":["../../../../libs/modules/software-management/client/src/lib/commands/accept-software-suggestion.command.ts"],"sourcesContent":["//#region ---- Imports ----\n\nimport { AXToastService } from '@acorex/components/toast';\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';\nimport { AXPCommand, resolveEntityActionRef, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport { RootConfig } from '@acorex-platform/module-software-management-client/contracts';\nimport { inject, Injectable } from '@angular/core';\n\nimport { resolveSoftwareText } from './software-command.util';\n\n//#endregion\n\n@Injectable({ providedIn: 'root' })\nexport class AcceptSoftwareSuggestionCommand implements AXPCommand<unknown, void> {\n //#region ---- Services & Dependencies ----\n\n private readonly entityService = inject(AXPEntityService);\n private readonly toastService = inject(AXToastService);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ---- Command Implementation ----\n\n async execute(input: unknown): AXPCommandExecuteResultPromise<void> {\n const resolved = resolveEntityActionRef(input);\n const refType = resolveSoftwareText(resolved?.refType);\n const refId = resolveSoftwareText(resolved?.refId);\n if (!refType || !refId) {\n return {\n success: false,\n message: {\n text: await this.translationService.translateAsync(\n '@software-management:messages.accept-suggestion.ref-required',\n ),\n },\n };\n }\n\n const [moduleName, entityName] = refType.split('.');\n if (moduleName !== RootConfig.module.name || !entityName) {\n return {\n success: false,\n message: {\n text: await this.translationService.translateAsync(\n '@software-management:messages.accept-suggestion.unsupported',\n ),\n },\n };\n }\n\n const record = (await this.entityService\n .withEntity(moduleName, entityName)\n .data()\n .byKey(refId)) as { origin?: string } | null;\n\n if (!record) {\n return { success: false, message: { text: 'Record not found' } };\n }\n\n if (record.origin !== 'suggestion') {\n this.toastService.show({\n color: 'warning',\n title: await this.translationService.translateAsync('@general:messages.generic.warning.title'),\n content: await this.translationService.translateAsync(\n '@software-management:messages.accept-suggestion.not-suggestion',\n ),\n closeButton: true,\n timeOut: 5000,\n });\n return { success: false };\n }\n\n await this.entityService.withEntity(moduleName, entityName).data().update(refId, {\n origin: 'approved-fact',\n acceptedAt: new Date().toISOString(),\n needsReview: false,\n reviewReason: '',\n } as never);\n\n this.toastService.show({\n color: 'success',\n title: await this.translationService.translateAsync('@general:messages.generic.success.title'),\n content: await this.translationService.translateAsync(\n '@software-management:messages.accept-suggestion.accepted',\n ),\n closeButton: true,\n timeOut: 4000,\n });\n\n return { success: true, kind: 'object', data: undefined };\n }\n\n //#endregion\n}\n\n//#endregion\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,182 @@
1
+ import { AXTranslationService } from '@acorex/core/translation';
2
+ import { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
3
+ import { resolveEntityActionRef } from '@acorex-platform/framework-shared/runtime';
4
+ import { RootConfig, canCompletePhase, nextSoftwarePhase, kickoffText, kickoffPlainTextFromVersion, discoveryReportFingerprint } from '@acorex-platform/module-software-management-client/contracts';
5
+ import * as i0 from '@angular/core';
6
+ import { inject, Injectable } from '@angular/core';
7
+ import { r as resolveSoftwareText } from './acorex-platform-module-software-management-client-software-command.util-BsoKQCX5.mjs';
8
+ import { l as loadIntroductionKickoffCheck, t as translateIntroductionExit } from './acorex-platform-module-software-management-client-introduction-exit-message.util-DShFM8MY.mjs';
9
+
10
+ //#region ---- Imports ----
11
+ //#endregion
12
+ class CompleteSoftwarePhaseActivity {
13
+ constructor() {
14
+ //#region ---- Services & Dependencies ----
15
+ this.entityService = inject(AXPEntityService);
16
+ this.i18n = inject(AXTranslationService);
17
+ }
18
+ //#endregion
19
+ //#region ---- Command Implementation ----
20
+ async execute(input) {
21
+ const softwareId = await this.resolveSoftwareId(input);
22
+ if (!softwareId) {
23
+ return {
24
+ success: false,
25
+ message: { text: 'softwareId is required' },
26
+ metadata: { outcome: 'Failed' },
27
+ };
28
+ }
29
+ const software = (await this.entityService.withEntity(RootConfig.module.name, RootConfig.entities.software.name).data().byKey(softwareId));
30
+ if (!software) {
31
+ return {
32
+ success: false,
33
+ message: { text: 'Software not found' },
34
+ metadata: { outcome: 'NotFound' },
35
+ };
36
+ }
37
+ const phase = (resolveSoftwareText(input?.phase) || resolveSoftwareText(software.currentPhase) || 'introduction');
38
+ const kickoff = await loadIntroductionKickoffCheck(this.entityService, software);
39
+ const discovery = phase === 'discovery' ? await this.loadDiscoveryCheck(software) : undefined;
40
+ const gate = canCompletePhase(phase, software, kickoff, discovery);
41
+ if (!gate.ok) {
42
+ const text = phase === 'introduction'
43
+ ? await translateIntroductionExit(this.i18n, gate)
44
+ : gate.message.startsWith('@')
45
+ ? await this.i18n.translateAsync(gate.message)
46
+ : gate.message;
47
+ return {
48
+ success: false,
49
+ message: { text, type: 'warning' },
50
+ metadata: { outcome: 'Failed', currentPhase: software.currentPhase },
51
+ };
52
+ }
53
+ const alreadyAdvanced = phase === 'introduction' ? Boolean(software.introductionCompletedAt) && software.currentPhase !== 'introduction' : software.currentPhase !== phase;
54
+ if (alreadyAdvanced) {
55
+ return {
56
+ success: true,
57
+ kind: 'object',
58
+ data: { valid: true, currentPhase: software.currentPhase },
59
+ metadata: { outcome: 'Done' },
60
+ };
61
+ }
62
+ if (phase === 'discovery' && gate.advance === false) {
63
+ return {
64
+ success: true,
65
+ kind: 'object',
66
+ data: { valid: true, currentPhase: software.currentPhase },
67
+ message: { text: gate.message },
68
+ metadata: { outcome: 'Done' },
69
+ };
70
+ }
71
+ const nextPhase = nextSoftwarePhase(phase);
72
+ const now = new Date().toISOString();
73
+ const patch = {
74
+ currentPhase: nextPhase ?? phase,
75
+ };
76
+ if (phase === 'introduction') {
77
+ patch['introductionCompletedAt'] = now;
78
+ }
79
+ if (!nextPhase) {
80
+ patch['definitionCompletedAt'] = now;
81
+ }
82
+ try {
83
+ await this.entityService
84
+ .withEntity(RootConfig.module.name, RootConfig.entities.software.name)
85
+ .data()
86
+ .update(softwareId, patch);
87
+ }
88
+ catch (error) {
89
+ const raw = error instanceof Error ? error.message : gate.message;
90
+ const text = raw.startsWith('@') ? await this.i18n.translateAsync(raw) : raw;
91
+ return {
92
+ success: false,
93
+ message: { text: text || gate.message, type: 'warning' },
94
+ metadata: { outcome: 'Failed', currentPhase: software.currentPhase },
95
+ };
96
+ }
97
+ return {
98
+ success: true,
99
+ kind: 'object',
100
+ data: { valid: true, currentPhase: String(patch['currentPhase']) },
101
+ metadata: { outcome: 'Done' },
102
+ };
103
+ }
104
+ //#endregion
105
+ //#region ---- Helpers ----
106
+ async resolveSoftwareId(input) {
107
+ const fromInput = resolveSoftwareText(input?.softwareId);
108
+ if (fromInput) {
109
+ return fromInput;
110
+ }
111
+ const resolved = resolveEntityActionRef(input);
112
+ return resolveSoftwareText(resolved?.refId);
113
+ }
114
+ async loadDiscoveryCheck(software) {
115
+ const kickoffVersionId = kickoffText(software.kickoffApprovedVersionId);
116
+ let kickoffPlainText = '';
117
+ if (kickoffVersionId) {
118
+ try {
119
+ const version = (await this.entityService.withEntity('DocumentManagement', 'DocumentVersion').data().byKey(kickoffVersionId));
120
+ kickoffPlainText = kickoffPlainTextFromVersion(version);
121
+ }
122
+ catch {
123
+ kickoffPlainText = '';
124
+ }
125
+ }
126
+ let findings = [];
127
+ try {
128
+ const page = await this.entityService
129
+ .withEntity(RootConfig.module.name, RootConfig.entities.discoveryItem.name)
130
+ .data()
131
+ .query({
132
+ skip: 0,
133
+ take: 500,
134
+ filter: { field: 'softwareId', operator: { type: 'equal' }, value: software.id },
135
+ });
136
+ findings = (page.items ?? []);
137
+ }
138
+ catch {
139
+ findings = [];
140
+ }
141
+ const documentId = kickoffText(software.discoveryReportDocumentId);
142
+ let statusId = '';
143
+ let hostVersionId = '';
144
+ if (documentId) {
145
+ try {
146
+ const document = (await this.entityService.withEntity('DocumentManagement', 'Document').data().byKey(documentId));
147
+ statusId = kickoffText(document?.statusId);
148
+ hostVersionId = kickoffText(document?.versionId);
149
+ }
150
+ catch {
151
+ statusId = '';
152
+ }
153
+ }
154
+ return {
155
+ currentPhase: software.currentPhase,
156
+ decision: software.discoveryDecision,
157
+ rationale: software.discoveryRationale,
158
+ kickoffApprovedVersionId: kickoffVersionId,
159
+ findings,
160
+ statusId,
161
+ hostVersionId,
162
+ approvedVersionId: software.discoveryApprovedVersionId,
163
+ approvedFingerprint: software.discoveryApprovedFingerprint,
164
+ reportFingerprint: discoveryReportFingerprint({
165
+ kickoffVersionId,
166
+ kickoffPlainText,
167
+ decision: kickoffText(software.discoveryDecision),
168
+ rationale: kickoffText(software.discoveryRationale),
169
+ findings,
170
+ }),
171
+ };
172
+ }
173
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CompleteSoftwarePhaseActivity, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
174
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CompleteSoftwarePhaseActivity, providedIn: 'root' }); }
175
+ }
176
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CompleteSoftwarePhaseActivity, decorators: [{
177
+ type: Injectable,
178
+ args: [{ providedIn: 'root' }]
179
+ }] });
180
+
181
+ export { CompleteSoftwarePhaseActivity };
182
+ //# sourceMappingURL=acorex-platform-module-software-management-client-complete-software-phase.activity-C56HhK20.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acorex-platform-module-software-management-client-complete-software-phase.activity-C56HhK20.mjs","sources":["../../../../libs/modules/software-management/client/src/lib/workflows/activities/complete-software-phase.activity.ts"],"sourcesContent":["//#region ---- Imports ----\n\nimport { AXTranslationService } from '@acorex/core/translation';\nimport { AXPEntityService } from '@acorex-platform/framework-client/layout/entity';\nimport { AXPCommand, resolveEntityActionRef, type AXPCommandExecuteResultPromise } from '@acorex-platform/framework-shared/runtime';\nimport {\n canCompletePhase,\n discoveryReportFingerprint,\n kickoffPlainTextFromVersion,\n kickoffText,\n nextSoftwarePhase,\n RootConfig,\n type AXMSoftwareManagementSoftwareEntityModel,\n type DiscoveryFindingRecord,\n type SoftwarePhase,\n} from '@acorex-platform/module-software-management-client/contracts';\nimport { inject, Injectable } from '@angular/core';\n\nimport { resolveSoftwareText } from '../../commands/software-command.util';\nimport { loadIntroductionKickoffCheck } from './load-introduction-kickoff-check';\nimport { translateIntroductionExit } from './introduction-exit-message.util';\n\n//#endregion\n\n//#region ---- Types ----\n\nexport interface CompleteSoftwarePhaseInput {\n softwareId?: string;\n phase?: SoftwarePhase;\n}\n\nexport interface CompleteSoftwarePhaseOutput {\n valid: boolean;\n currentPhase?: string;\n}\n\n//#endregion\n\n@Injectable({ providedIn: 'root' })\nexport class CompleteSoftwarePhaseActivity implements AXPCommand<CompleteSoftwarePhaseInput, CompleteSoftwarePhaseOutput> {\n //#region ---- Services & Dependencies ----\n\n private readonly entityService = inject(AXPEntityService);\n private readonly i18n = inject(AXTranslationService);\n\n //#endregion\n\n //#region ---- Command Implementation ----\n\n async execute(input: CompleteSoftwarePhaseInput): AXPCommandExecuteResultPromise<CompleteSoftwarePhaseOutput> {\n const softwareId = await this.resolveSoftwareId(input);\n if (!softwareId) {\n return {\n success: false,\n message: { text: 'softwareId is required' },\n metadata: { outcome: 'Failed' },\n };\n }\n\n const software = (await this.entityService.withEntity(RootConfig.module.name, RootConfig.entities.software.name).data().byKey(softwareId)) as AXMSoftwareManagementSoftwareEntityModel | null;\n\n if (!software) {\n return {\n success: false,\n message: { text: 'Software not found' },\n metadata: { outcome: 'NotFound' },\n };\n }\n\n const phase = (resolveSoftwareText(input?.phase) || resolveSoftwareText(software.currentPhase) || 'introduction') as SoftwarePhase;\n\n const kickoff = await loadIntroductionKickoffCheck(this.entityService, software);\n const discovery = phase === 'discovery' ? await this.loadDiscoveryCheck(software) : undefined;\n const gate = canCompletePhase(phase, software, kickoff, discovery);\n if (!gate.ok) {\n const text =\n phase === 'introduction'\n ? await translateIntroductionExit(this.i18n, gate)\n : gate.message.startsWith('@')\n ? await this.i18n.translateAsync(gate.message)\n : gate.message;\n return {\n success: false,\n message: { text, type: 'warning' },\n metadata: { outcome: 'Failed', currentPhase: software.currentPhase },\n };\n }\n\n const alreadyAdvanced = phase === 'introduction' ? Boolean(software.introductionCompletedAt) && software.currentPhase !== 'introduction' : software.currentPhase !== phase;\n\n if (alreadyAdvanced) {\n return {\n success: true,\n kind: 'object',\n data: { valid: true, currentPhase: software.currentPhase },\n metadata: { outcome: 'Done' },\n };\n }\n\n if (phase === 'discovery' && gate.advance === false) {\n return {\n success: true,\n kind: 'object',\n data: { valid: true, currentPhase: software.currentPhase },\n message: { text: gate.message },\n metadata: { outcome: 'Done' },\n };\n }\n\n const nextPhase = nextSoftwarePhase(phase);\n const now = new Date().toISOString();\n const patch: Record<string, unknown> = {\n currentPhase: nextPhase ?? phase,\n };\n\n if (phase === 'introduction') {\n patch['introductionCompletedAt'] = now;\n }\n\n if (!nextPhase) {\n patch['definitionCompletedAt'] = now;\n }\n\n try {\n await this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.software.name)\n .data()\n .update(softwareId, patch as never);\n } catch (error) {\n const raw = error instanceof Error ? error.message : gate.message;\n const text = raw.startsWith('@') ? await this.i18n.translateAsync(raw) : raw;\n return {\n success: false,\n message: { text: text || gate.message, type: 'warning' },\n metadata: { outcome: 'Failed', currentPhase: software.currentPhase },\n };\n }\n\n return {\n success: true,\n kind: 'object',\n data: { valid: true, currentPhase: String(patch['currentPhase']) },\n metadata: { outcome: 'Done' },\n };\n }\n\n //#endregion\n\n //#region ---- Helpers ----\n\n private async resolveSoftwareId(input: CompleteSoftwarePhaseInput): Promise<string> {\n const fromInput = resolveSoftwareText(input?.softwareId);\n if (fromInput) {\n return fromInput;\n }\n\n const resolved = resolveEntityActionRef(input);\n return resolveSoftwareText(resolved?.refId);\n }\n\n private async loadDiscoveryCheck(software: AXMSoftwareManagementSoftwareEntityModel) {\n const kickoffVersionId = kickoffText(software.kickoffApprovedVersionId);\n let kickoffPlainText = '';\n if (kickoffVersionId) {\n try {\n const version = (await this.entityService.withEntity('DocumentManagement', 'DocumentVersion').data().byKey(kickoffVersionId)) as { metaDataForm?: unknown } | null;\n kickoffPlainText = kickoffPlainTextFromVersion(version);\n } catch {\n kickoffPlainText = '';\n }\n }\n\n let findings: DiscoveryFindingRecord[] = [];\n try {\n const page = await this.entityService\n .withEntity(RootConfig.module.name, RootConfig.entities.discoveryItem.name)\n .data()\n .query({\n skip: 0,\n take: 500,\n filter: { field: 'softwareId', operator: { type: 'equal' }, value: software.id },\n });\n findings = (page.items ?? []) as DiscoveryFindingRecord[];\n } catch {\n findings = [];\n }\n\n const documentId = kickoffText(software.discoveryReportDocumentId);\n let statusId = '';\n let hostVersionId = '';\n if (documentId) {\n try {\n const document = (await this.entityService.withEntity('DocumentManagement', 'Document').data().byKey(documentId)) as { statusId?: unknown; versionId?: unknown } | null;\n statusId = kickoffText(document?.statusId);\n hostVersionId = kickoffText(document?.versionId);\n } catch {\n statusId = '';\n }\n }\n\n return {\n currentPhase: software.currentPhase,\n decision: software.discoveryDecision,\n rationale: software.discoveryRationale,\n kickoffApprovedVersionId: kickoffVersionId,\n findings,\n statusId,\n hostVersionId,\n approvedVersionId: software.discoveryApprovedVersionId,\n approvedFingerprint: software.discoveryApprovedFingerprint,\n reportFingerprint: discoveryReportFingerprint({\n kickoffVersionId,\n kickoffPlainText,\n decision: kickoffText(software.discoveryDecision),\n rationale: kickoffText(software.discoveryRationale),\n findings,\n }),\n };\n }\n\n //#endregion\n}\n\n//#endregion\n"],"names":[],"mappings":"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"}