@striae-org/striae 3.2.0 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -32
- package/app/components/actions/case-export/core-export.ts +2 -2
- package/app/components/actions/case-export/data-processing.ts +65 -10
- package/app/components/actions/case-export/download-handlers.ts +130 -44
- package/app/components/actions/case-export/metadata-helpers.ts +32 -14
- package/app/components/actions/case-import/annotation-import.ts +2 -2
- package/app/components/actions/case-import/confirmation-import.ts +3 -3
- package/app/components/actions/case-import/image-operations.ts +1 -1
- package/app/components/actions/case-import/orchestrator.ts +4 -4
- package/app/components/actions/case-import/storage-operations.ts +7 -7
- package/app/components/actions/case-import/validation.ts +3 -3
- package/app/components/actions/case-import/zip-processing.ts +3 -3
- package/app/components/actions/case-manage.ts +3 -3
- package/app/components/actions/confirm-export.ts +3 -3
- package/app/components/actions/generate-pdf.ts +3 -3
- package/app/components/actions/image-manage.ts +3 -3
- package/app/components/actions/notes-manage.ts +3 -3
- package/app/components/actions/signout.tsx +1 -1
- package/app/components/audit/user-audit-viewer.tsx +2 -3
- package/app/components/auth/auth-provider.tsx +2 -2
- package/app/components/auth/mfa-enrollment.tsx +3 -3
- package/app/components/auth/mfa-verification.tsx +4 -4
- package/app/components/canvas/box-annotations/box-annotations.tsx +2 -2
- package/app/components/canvas/canvas.tsx +1 -1
- package/app/components/canvas/confirmation/confirmation.tsx +1 -1
- package/app/components/form/base-form.tsx +1 -1
- package/app/components/sidebar/case-export/case-export.tsx +15 -15
- package/app/components/sidebar/case-import/case-import.tsx +2 -2
- package/app/components/sidebar/case-import/components/CasePreviewSection.tsx +1 -1
- package/app/components/sidebar/case-import/components/ConfirmationDialog.tsx +1 -1
- package/app/components/sidebar/case-import/hooks/useFilePreview.ts +3 -3
- package/app/components/sidebar/case-import/hooks/useImportExecution.ts +2 -2
- package/app/components/sidebar/cases/case-sidebar.tsx +27 -19
- package/app/components/sidebar/cases/cases-modal.tsx +1 -1
- package/app/components/sidebar/files/files-modal.tsx +3 -2
- package/app/components/sidebar/notes/notes-sidebar.tsx +3 -3
- package/app/components/sidebar/sidebar-container.tsx +5 -4
- package/app/components/sidebar/sidebar.tsx +2 -2
- package/app/components/sidebar/upload/image-upload-zone.tsx +2 -2
- package/app/components/theme-provider/theme-provider.tsx +1 -1
- package/app/components/user/delete-account.tsx +1 -1
- package/app/components/user/manage-profile.tsx +2 -2
- package/app/components/user/mfa-phone-update.tsx +2 -2
- package/app/contexts/auth.context.ts +1 -1
- package/app/entry.client.tsx +12 -12
- package/app/entry.server.tsx +4 -4
- package/app/hooks/useInactivityTimeout.ts +1 -1
- package/app/root.tsx +3 -3
- package/app/routes/auth/emailActionHandler.tsx +3 -3
- package/app/routes/auth/emailVerification.tsx +3 -3
- package/app/routes/auth/login.tsx +6 -6
- package/app/routes/auth/passwordReset.tsx +3 -3
- package/app/routes/auth/route.ts +1 -1
- package/app/routes/striae/striae.tsx +2 -2
- package/app/services/audit/audit-console-logger.ts +46 -0
- package/app/services/audit/audit-export-csv.ts +126 -0
- package/app/services/audit/audit-export-report.ts +174 -0
- package/app/services/audit/audit-export-signing.ts +85 -0
- package/app/services/audit/audit-export.service.ts +334 -0
- package/app/services/audit/audit-file-type.ts +13 -0
- package/app/services/audit/audit-query-helpers.ts +88 -0
- package/app/services/audit/audit-worker-client.ts +95 -0
- package/app/services/audit/audit.service.ts +990 -0
- package/app/services/audit/builders/audit-entry-builder.ts +32 -0
- package/app/services/audit/builders/audit-event-builders-annotation.ts +150 -0
- package/app/services/audit/builders/audit-event-builders-case-file.ts +249 -0
- package/app/services/audit/builders/audit-event-builders-user-security.ts +449 -0
- package/app/services/audit/builders/audit-event-builders-workflow.ts +272 -0
- package/app/services/audit/builders/index.ts +40 -0
- package/app/services/audit/index.ts +2 -0
- package/app/types/case.ts +2 -2
- package/app/types/exceljs-bare.d.ts +9 -0
- package/app/types/user.ts +1 -1
- package/app/utils/audit-export-signature.ts +2 -2
- package/app/utils/confirmation-signature.ts +3 -3
- package/app/utils/data-operations.ts +5 -5
- package/app/utils/mfa-phone.ts +1 -1
- package/app/utils/mfa.ts +1 -1
- package/app/utils/permissions.ts +2 -2
- package/functions/[[path]].ts +2 -2
- package/package.json +34 -20
- package/public/vendor/exceljs.LICENSE +22 -0
- package/public/vendor/exceljs.bare.min.js +45 -0
- package/scripts/deploy-all.sh +52 -0
- package/scripts/deploy-config.sh +282 -1
- package/tsconfig.json +18 -8
- package/vite.config.ts +6 -22
- package/worker-configuration.d.ts +4435 -562
- package/workers/audit-worker/package.json +8 -4
- package/workers/audit-worker/wrangler.jsonc.example +1 -1
- package/workers/data-worker/package.json +8 -4
- package/workers/data-worker/src/data-worker.example.ts +3 -3
- package/workers/data-worker/wrangler.jsonc.example +1 -1
- package/workers/image-worker/package.json +8 -4
- package/workers/image-worker/wrangler.jsonc.example +1 -1
- package/workers/keys-worker/package.json +8 -4
- package/workers/keys-worker/wrangler.jsonc.example +1 -1
- package/workers/pdf-worker/package.json +8 -4
- package/workers/pdf-worker/src/{generated-assets.ts → assets/generated-assets.ts} +117 -117
- package/workers/pdf-worker/src/{format-striae.ts → formats/format-striae.ts} +535 -535
- package/workers/pdf-worker/src/pdf-worker.example.ts +1 -1
- package/workers/pdf-worker/wrangler.jsonc.example +1 -1
- package/workers/user-worker/package.json +8 -4
- package/workers/user-worker/wrangler.jsonc.example +1 -1
- package/wrangler.toml.example +1 -1
- package/app/services/audit-export.service.ts +0 -755
- package/app/services/audit.service.ts +0 -1474
- /package/app/services/{firebase-errors.ts → firebase/errors.ts} +0 -0
- /package/app/services/{firebase.ts → firebase/index.ts} +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type CreateAuditEntryParams, type ValidationAuditEntry } from '~/types';
|
|
2
|
+
|
|
3
|
+
export const buildValidationAuditEntry = (
|
|
4
|
+
params: CreateAuditEntryParams,
|
|
5
|
+
timestamp: string = new Date().toISOString()
|
|
6
|
+
): ValidationAuditEntry => {
|
|
7
|
+
return {
|
|
8
|
+
timestamp,
|
|
9
|
+
userId: params.userId,
|
|
10
|
+
userEmail: params.userEmail,
|
|
11
|
+
action: params.action,
|
|
12
|
+
result: params.result,
|
|
13
|
+
details: {
|
|
14
|
+
fileName: params.fileName,
|
|
15
|
+
fileType: params.fileType,
|
|
16
|
+
hashValid: params.hashValid,
|
|
17
|
+
validationErrors: params.validationErrors || [],
|
|
18
|
+
caseNumber: params.caseNumber,
|
|
19
|
+
confirmationId: params.confirmationId,
|
|
20
|
+
originalExaminerUid: params.originalExaminerUid,
|
|
21
|
+
reviewingExaminerUid: params.reviewingExaminerUid,
|
|
22
|
+
workflowPhase: params.workflowPhase,
|
|
23
|
+
securityChecks: params.securityChecks,
|
|
24
|
+
performanceMetrics: params.performanceMetrics,
|
|
25
|
+
caseDetails: params.caseDetails,
|
|
26
|
+
fileDetails: params.fileDetails,
|
|
27
|
+
annotationDetails: params.annotationDetails,
|
|
28
|
+
sessionDetails: params.sessionDetails,
|
|
29
|
+
securityDetails: params.securityDetails
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { User } from 'firebase/auth';
|
|
2
|
+
import { type CreateAuditEntryParams } from '~/types';
|
|
3
|
+
|
|
4
|
+
type AnnotationSnapshot = Record<string, unknown> & {
|
|
5
|
+
type?: 'measurement' | 'identification' | 'comparison' | 'note' | 'region';
|
|
6
|
+
position?: { x: number; y: number };
|
|
7
|
+
size?: { width: number; height: number };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const toAnnotationSnapshot = (value: unknown): AnnotationSnapshot | undefined => {
|
|
11
|
+
if (typeof value !== 'object' || value === null) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return value as AnnotationSnapshot;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
interface BuildAnnotationCreateAuditParamsInput {
|
|
19
|
+
user: User;
|
|
20
|
+
annotationId: string;
|
|
21
|
+
annotationType: 'measurement' | 'identification' | 'comparison' | 'note' | 'region';
|
|
22
|
+
annotationData: unknown;
|
|
23
|
+
caseNumber: string;
|
|
24
|
+
tool?: string;
|
|
25
|
+
imageFileId?: string;
|
|
26
|
+
originalImageFileName?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const buildAnnotationCreateAuditParams = (
|
|
30
|
+
input: BuildAnnotationCreateAuditParamsInput
|
|
31
|
+
): CreateAuditEntryParams => {
|
|
32
|
+
const annotationSnapshot = toAnnotationSnapshot(input.annotationData);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
userId: input.user.uid,
|
|
36
|
+
userEmail: input.user.email || '',
|
|
37
|
+
action: 'annotation-create',
|
|
38
|
+
result: 'success',
|
|
39
|
+
fileName: `annotation-${input.annotationId}.json`,
|
|
40
|
+
fileType: 'json-data',
|
|
41
|
+
validationErrors: [],
|
|
42
|
+
caseNumber: input.caseNumber,
|
|
43
|
+
workflowPhase: 'casework',
|
|
44
|
+
annotationDetails: {
|
|
45
|
+
annotationId: input.annotationId,
|
|
46
|
+
annotationType: input.annotationType,
|
|
47
|
+
annotationData: input.annotationData,
|
|
48
|
+
tool: input.tool,
|
|
49
|
+
canvasPosition: annotationSnapshot?.position,
|
|
50
|
+
annotationSize: annotationSnapshot?.size
|
|
51
|
+
},
|
|
52
|
+
fileDetails: input.imageFileId || input.originalImageFileName
|
|
53
|
+
? {
|
|
54
|
+
fileId: input.imageFileId,
|
|
55
|
+
originalFileName: input.originalImageFileName,
|
|
56
|
+
fileSize: 0,
|
|
57
|
+
mimeType: 'image/*',
|
|
58
|
+
uploadMethod: 'api'
|
|
59
|
+
}
|
|
60
|
+
: undefined
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
interface BuildAnnotationEditAuditParamsInput {
|
|
65
|
+
user: User;
|
|
66
|
+
annotationId: string;
|
|
67
|
+
previousValue: unknown;
|
|
68
|
+
newValue: unknown;
|
|
69
|
+
caseNumber: string;
|
|
70
|
+
tool?: string;
|
|
71
|
+
imageFileId?: string;
|
|
72
|
+
originalImageFileName?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const buildAnnotationEditAuditParams = (
|
|
76
|
+
input: BuildAnnotationEditAuditParamsInput
|
|
77
|
+
): CreateAuditEntryParams => {
|
|
78
|
+
const newValueSnapshot = toAnnotationSnapshot(input.newValue);
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
userId: input.user.uid,
|
|
82
|
+
userEmail: input.user.email || '',
|
|
83
|
+
action: 'annotation-edit',
|
|
84
|
+
result: 'success',
|
|
85
|
+
fileName: `annotation-${input.annotationId}.json`,
|
|
86
|
+
fileType: 'json-data',
|
|
87
|
+
validationErrors: [],
|
|
88
|
+
caseNumber: input.caseNumber,
|
|
89
|
+
workflowPhase: 'casework',
|
|
90
|
+
annotationDetails: {
|
|
91
|
+
annotationId: input.annotationId,
|
|
92
|
+
annotationType: newValueSnapshot?.type,
|
|
93
|
+
annotationData: input.newValue,
|
|
94
|
+
previousValue: input.previousValue,
|
|
95
|
+
tool: input.tool
|
|
96
|
+
},
|
|
97
|
+
fileDetails: input.imageFileId || input.originalImageFileName
|
|
98
|
+
? {
|
|
99
|
+
fileId: input.imageFileId,
|
|
100
|
+
originalFileName: input.originalImageFileName,
|
|
101
|
+
fileSize: 0,
|
|
102
|
+
mimeType: 'image/*',
|
|
103
|
+
uploadMethod: 'api'
|
|
104
|
+
}
|
|
105
|
+
: undefined
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
interface BuildAnnotationDeleteAuditParamsInput {
|
|
110
|
+
user: User;
|
|
111
|
+
annotationId: string;
|
|
112
|
+
annotationData: unknown;
|
|
113
|
+
caseNumber: string;
|
|
114
|
+
deleteReason?: string;
|
|
115
|
+
imageFileId?: string;
|
|
116
|
+
originalImageFileName?: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const buildAnnotationDeleteAuditParams = (
|
|
120
|
+
input: BuildAnnotationDeleteAuditParamsInput
|
|
121
|
+
): CreateAuditEntryParams => {
|
|
122
|
+
const annotationSnapshot = toAnnotationSnapshot(input.annotationData);
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
userId: input.user.uid,
|
|
126
|
+
userEmail: input.user.email || '',
|
|
127
|
+
action: 'annotation-delete',
|
|
128
|
+
result: 'success',
|
|
129
|
+
fileName: `annotation-${input.annotationId}.json`,
|
|
130
|
+
fileType: 'json-data',
|
|
131
|
+
validationErrors: [],
|
|
132
|
+
caseNumber: input.caseNumber,
|
|
133
|
+
workflowPhase: 'casework',
|
|
134
|
+
annotationDetails: {
|
|
135
|
+
annotationId: input.annotationId,
|
|
136
|
+
annotationType: annotationSnapshot?.type,
|
|
137
|
+
annotationData: input.annotationData,
|
|
138
|
+
tool: input.deleteReason
|
|
139
|
+
},
|
|
140
|
+
fileDetails: input.imageFileId || input.originalImageFileName
|
|
141
|
+
? {
|
|
142
|
+
fileId: input.imageFileId,
|
|
143
|
+
originalFileName: input.originalImageFileName,
|
|
144
|
+
fileSize: 0,
|
|
145
|
+
mimeType: 'image/*',
|
|
146
|
+
uploadMethod: 'api'
|
|
147
|
+
}
|
|
148
|
+
: undefined
|
|
149
|
+
};
|
|
150
|
+
};
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import type { User } from 'firebase/auth';
|
|
2
|
+
import { type AuditResult, type CreateAuditEntryParams } from '~/types';
|
|
3
|
+
import { getAuditFileTypeFromMime, isImageMimeType } from '../audit-file-type';
|
|
4
|
+
|
|
5
|
+
interface BuildCaseCreationAuditParamsInput {
|
|
6
|
+
user: User;
|
|
7
|
+
caseNumber: string;
|
|
8
|
+
caseName: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const buildCaseCreationAuditParams = (
|
|
12
|
+
input: BuildCaseCreationAuditParamsInput
|
|
13
|
+
): CreateAuditEntryParams => {
|
|
14
|
+
return {
|
|
15
|
+
userId: input.user.uid,
|
|
16
|
+
userEmail: input.user.email || '',
|
|
17
|
+
action: 'case-create',
|
|
18
|
+
result: 'success',
|
|
19
|
+
fileName: `${input.caseNumber}.case`,
|
|
20
|
+
fileType: 'case-package',
|
|
21
|
+
validationErrors: [],
|
|
22
|
+
caseNumber: input.caseNumber,
|
|
23
|
+
workflowPhase: 'casework',
|
|
24
|
+
caseDetails: {
|
|
25
|
+
newCaseName: input.caseName,
|
|
26
|
+
createdDate: new Date().toISOString(),
|
|
27
|
+
totalFiles: 0,
|
|
28
|
+
totalAnnotations: 0
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
interface BuildCaseRenameAuditParamsInput {
|
|
34
|
+
user: User;
|
|
35
|
+
caseNumber: string;
|
|
36
|
+
oldName: string;
|
|
37
|
+
newName: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const buildCaseRenameAuditParams = (
|
|
41
|
+
input: BuildCaseRenameAuditParamsInput
|
|
42
|
+
): CreateAuditEntryParams => {
|
|
43
|
+
return {
|
|
44
|
+
userId: input.user.uid,
|
|
45
|
+
userEmail: input.user.email || '',
|
|
46
|
+
action: 'case-rename',
|
|
47
|
+
result: 'success',
|
|
48
|
+
fileName: `${input.caseNumber}.case`,
|
|
49
|
+
fileType: 'case-package',
|
|
50
|
+
validationErrors: [],
|
|
51
|
+
caseNumber: input.caseNumber,
|
|
52
|
+
workflowPhase: 'casework',
|
|
53
|
+
caseDetails: {
|
|
54
|
+
oldCaseName: input.oldName,
|
|
55
|
+
newCaseName: input.newName,
|
|
56
|
+
lastModified: new Date().toISOString()
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
interface BuildCaseDeletionAuditParamsInput {
|
|
62
|
+
user: User;
|
|
63
|
+
caseNumber: string;
|
|
64
|
+
caseName: string;
|
|
65
|
+
deleteReason: string;
|
|
66
|
+
backupCreated?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const buildCaseDeletionAuditParams = (
|
|
70
|
+
input: BuildCaseDeletionAuditParamsInput
|
|
71
|
+
): CreateAuditEntryParams => {
|
|
72
|
+
return {
|
|
73
|
+
userId: input.user.uid,
|
|
74
|
+
userEmail: input.user.email || '',
|
|
75
|
+
action: 'case-delete',
|
|
76
|
+
result: 'success',
|
|
77
|
+
fileName: `${input.caseNumber}.case`,
|
|
78
|
+
fileType: 'case-package',
|
|
79
|
+
validationErrors: [],
|
|
80
|
+
caseNumber: input.caseNumber,
|
|
81
|
+
workflowPhase: 'casework',
|
|
82
|
+
caseDetails: {
|
|
83
|
+
newCaseName: input.caseName,
|
|
84
|
+
deleteReason: input.deleteReason,
|
|
85
|
+
backupCreated: input.backupCreated || false,
|
|
86
|
+
lastModified: new Date().toISOString()
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
interface BuildFileUploadAuditParamsInput {
|
|
92
|
+
user: User;
|
|
93
|
+
fileName: string;
|
|
94
|
+
fileSize: number;
|
|
95
|
+
mimeType: string;
|
|
96
|
+
uploadMethod: 'drag-drop' | 'file-picker' | 'api' | 'import';
|
|
97
|
+
caseNumber: string;
|
|
98
|
+
result?: AuditResult;
|
|
99
|
+
processingTime?: number;
|
|
100
|
+
fileId?: string;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const buildFileUploadAuditParams = (
|
|
104
|
+
input: BuildFileUploadAuditParamsInput
|
|
105
|
+
): CreateAuditEntryParams => {
|
|
106
|
+
const result = input.result || 'success';
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
userId: input.user.uid,
|
|
110
|
+
userEmail: input.user.email || '',
|
|
111
|
+
action: 'file-upload',
|
|
112
|
+
result,
|
|
113
|
+
fileName: input.fileName,
|
|
114
|
+
fileType: getAuditFileTypeFromMime(input.mimeType),
|
|
115
|
+
validationErrors: [],
|
|
116
|
+
caseNumber: input.caseNumber,
|
|
117
|
+
workflowPhase: 'casework',
|
|
118
|
+
fileDetails: {
|
|
119
|
+
fileId: input.fileId || undefined,
|
|
120
|
+
originalFileName: input.fileName,
|
|
121
|
+
fileSize: input.fileSize,
|
|
122
|
+
mimeType: input.mimeType,
|
|
123
|
+
uploadMethod: input.uploadMethod,
|
|
124
|
+
processingTime: input.processingTime,
|
|
125
|
+
thumbnailGenerated: result === 'success' && isImageMimeType(input.mimeType)
|
|
126
|
+
},
|
|
127
|
+
performanceMetrics: input.processingTime
|
|
128
|
+
? {
|
|
129
|
+
processingTimeMs: input.processingTime,
|
|
130
|
+
fileSizeBytes: input.fileSize
|
|
131
|
+
}
|
|
132
|
+
: undefined
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
interface BuildFileDeletionAuditParamsInput {
|
|
137
|
+
user: User;
|
|
138
|
+
fileName: string;
|
|
139
|
+
fileSize: number;
|
|
140
|
+
deleteReason: string;
|
|
141
|
+
caseNumber: string;
|
|
142
|
+
fileId?: string;
|
|
143
|
+
originalFileName?: string;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export const buildFileDeletionAuditParams = (
|
|
147
|
+
input: BuildFileDeletionAuditParamsInput
|
|
148
|
+
): CreateAuditEntryParams => {
|
|
149
|
+
return {
|
|
150
|
+
userId: input.user.uid,
|
|
151
|
+
userEmail: input.user.email || '',
|
|
152
|
+
action: 'file-delete',
|
|
153
|
+
result: 'success',
|
|
154
|
+
fileName: input.fileName,
|
|
155
|
+
fileType: 'unknown',
|
|
156
|
+
validationErrors: [],
|
|
157
|
+
caseNumber: input.caseNumber,
|
|
158
|
+
workflowPhase: 'casework',
|
|
159
|
+
fileDetails: {
|
|
160
|
+
fileId: input.fileId || undefined,
|
|
161
|
+
originalFileName: input.originalFileName,
|
|
162
|
+
fileSize: input.fileSize,
|
|
163
|
+
deleteReason: input.deleteReason
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
interface BuildFileAccessAuditParamsInput {
|
|
169
|
+
user: User;
|
|
170
|
+
fileName: string;
|
|
171
|
+
fileId: string;
|
|
172
|
+
accessMethod: 'direct-url' | 'signed-url' | 'download';
|
|
173
|
+
caseNumber: string;
|
|
174
|
+
result?: AuditResult;
|
|
175
|
+
processingTime?: number;
|
|
176
|
+
accessReason?: string;
|
|
177
|
+
originalFileName?: string;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export const buildFileAccessAuditParams = (
|
|
181
|
+
input: BuildFileAccessAuditParamsInput
|
|
182
|
+
): CreateAuditEntryParams => {
|
|
183
|
+
const result = input.result || 'success';
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
userId: input.user.uid,
|
|
187
|
+
userEmail: input.user.email || '',
|
|
188
|
+
action: 'file-access',
|
|
189
|
+
result,
|
|
190
|
+
fileName: input.fileName,
|
|
191
|
+
fileType: 'image-file',
|
|
192
|
+
validationErrors: result === 'failure' ? ['File access failed'] : [],
|
|
193
|
+
caseNumber: input.caseNumber,
|
|
194
|
+
workflowPhase: 'casework',
|
|
195
|
+
fileDetails: {
|
|
196
|
+
fileId: input.fileId,
|
|
197
|
+
originalFileName: input.originalFileName,
|
|
198
|
+
fileSize: 0,
|
|
199
|
+
uploadMethod: input.accessMethod,
|
|
200
|
+
processingTime: input.processingTime,
|
|
201
|
+
sourceLocation: input.accessReason || 'Image viewer'
|
|
202
|
+
},
|
|
203
|
+
performanceMetrics: input.processingTime
|
|
204
|
+
? {
|
|
205
|
+
processingTimeMs: input.processingTime,
|
|
206
|
+
fileSizeBytes: 0
|
|
207
|
+
}
|
|
208
|
+
: undefined
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
interface BuildPDFGenerationAuditParamsInput {
|
|
213
|
+
user: User;
|
|
214
|
+
fileName: string;
|
|
215
|
+
caseNumber: string;
|
|
216
|
+
result: AuditResult;
|
|
217
|
+
processingTime: number;
|
|
218
|
+
fileSize?: number;
|
|
219
|
+
errors?: string[];
|
|
220
|
+
sourceFileId?: string;
|
|
221
|
+
sourceFileName?: string;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export const buildPDFGenerationAuditParams = (
|
|
225
|
+
input: BuildPDFGenerationAuditParamsInput
|
|
226
|
+
): CreateAuditEntryParams => {
|
|
227
|
+
return {
|
|
228
|
+
userId: input.user.uid,
|
|
229
|
+
userEmail: input.user.email || '',
|
|
230
|
+
action: 'pdf-generate',
|
|
231
|
+
result: input.result,
|
|
232
|
+
fileName: input.fileName,
|
|
233
|
+
fileType: 'pdf-document',
|
|
234
|
+
validationErrors: input.errors || [],
|
|
235
|
+
caseNumber: input.caseNumber,
|
|
236
|
+
workflowPhase: 'casework',
|
|
237
|
+
performanceMetrics: {
|
|
238
|
+
processingTimeMs: input.processingTime,
|
|
239
|
+
fileSizeBytes: input.fileSize || 0
|
|
240
|
+
},
|
|
241
|
+
fileDetails: input.sourceFileId && input.sourceFileName
|
|
242
|
+
? {
|
|
243
|
+
fileId: input.sourceFileId,
|
|
244
|
+
originalFileName: input.sourceFileName,
|
|
245
|
+
fileSize: 0
|
|
246
|
+
}
|
|
247
|
+
: undefined
|
|
248
|
+
};
|
|
249
|
+
};
|