55 toExternalEvidenceFormType ,
66} from '@trycompai/company' ;
77import { db } from '@db' ;
8+ import { ISO27001_FRAMEWORK_NAMES } from '../soa/utils/constants' ;
89import { filterComplianceMembers } from '../utils/compliance-filters' ;
910
1011const SIX_MONTHS_MS = 6 * 30 * 24 * 60 * 60 * 1000 ;
@@ -185,11 +186,24 @@ export async function getOverviewScores(organizationId: string) {
185186}
186187
187188async function computeDocumentsScore ( organizationId : string ) {
188- const groupedStatuses = await db . evidenceSubmission . groupBy ( {
189- by : [ 'formType' ] ,
190- where : { organizationId } ,
191- _max : { submittedAt : true } ,
192- } ) ;
189+ const [ groupedStatuses , isoFrameworkInstances ] = await Promise . all ( [
190+ db . evidenceSubmission . groupBy ( {
191+ by : [ 'formType' ] ,
192+ where : { organizationId } ,
193+ _max : { submittedAt : true } ,
194+ } ) ,
195+ db . frameworkInstance . findMany ( {
196+ where : {
197+ organizationId,
198+ framework : {
199+ name : {
200+ in : ISO27001_FRAMEWORK_NAMES ,
201+ } ,
202+ } ,
203+ } ,
204+ select : { frameworkId : true } ,
205+ } ) ,
206+ ] ) ;
193207
194208 const statuses : Record < string , { lastSubmittedAt : string | null } > = { } ;
195209 for ( const form of evidenceFormDefinitionList ) {
@@ -204,8 +218,7 @@ async function computeDocumentsScore(organizationId: string) {
204218 const includedForms = evidenceFormDefinitionList . filter (
205219 ( f ) => ! f . hidden && ! f . optional ,
206220 ) ;
207- const totalDocuments = includedForms . length ;
208- const outstandingDocuments = includedForms . reduce ( ( count , form ) => {
221+ const nonSOAOutstandingDocuments = includedForms . reduce ( ( count , form ) => {
209222 if ( form . type === 'meeting' ) {
210223 const allMeetingsOutstanding = meetingSubTypeValues . every ( ( subType ) => {
211224 const lastSubmitted = statuses [ subType ] ?. lastSubmittedAt ;
@@ -223,6 +236,37 @@ async function computeDocumentsScore(organizationId: string) {
223236 return isOutstanding ? count + 1 : count ;
224237 } , 0 ) ;
225238
239+ const isoFrameworkIds = isoFrameworkInstances
240+ . map ( ( instance ) => instance . frameworkId )
241+ . filter ( ( id ) : id is string => ! ! id ) ;
242+ const hasSOADocumentRequirement = isoFrameworkIds . length > 0 ;
243+
244+ let soaCompleted = false ;
245+ if ( hasSOADocumentRequirement ) {
246+ const latestSOADocument = await db . sOADocument . findFirst ( {
247+ where : {
248+ organizationId,
249+ isLatest : true ,
250+ frameworkId : { in : isoFrameworkIds } ,
251+ } ,
252+ select : {
253+ approvedAt : true ,
254+ status : true ,
255+ } ,
256+ orderBy : {
257+ updatedAt : 'desc' ,
258+ } ,
259+ } ) ;
260+ soaCompleted =
261+ latestSOADocument ?. status === 'completed' &&
262+ ! ! latestSOADocument . approvedAt ;
263+ }
264+
265+ const soaTotalDocuments = hasSOADocumentRequirement ? 1 : 0 ;
266+ const soaOutstandingDocuments = hasSOADocumentRequirement && ! soaCompleted ? 1 : 0 ;
267+ const totalDocuments = includedForms . length + soaTotalDocuments ;
268+ const outstandingDocuments = nonSOAOutstandingDocuments + soaOutstandingDocuments ;
269+
226270 return {
227271 totalDocuments,
228272 completedDocuments : totalDocuments - outstandingDocuments ,
0 commit comments