Evidence & Graph Relationships Constraints¶
This spec outlines the guarantees around how evidence is stored, linked, annotated, and analyzed so any new feature interacting with audit data can align with the backend’s expectations (backend/src/routes/evidence.ts, backend/src/services/graph.service.ts, backend/src/services/analysis.service.ts).
1. Access Control & Listing¶
- Authenticated entry: The
/api/evidencerouter is gated by the sharedauthenticatemiddleware; every query must observereq.user. - Role-based filtering: The list and stats endpoints only succeed when the requesting user matches one of the following:
- Auditor/Reviewer assigned to the project.
- Customer owning the project (or a demo user linked via
DEMO_MANAGER_ID). - Manager (via
projectShares) or admin when explicitly shared. - Demo visibility:
showDemoProjectsflips to true when a new/demo user lacks a manager or inheritsDEMO_MANAGER_ID, allowing them to view demo evidence without breaking RBAC. - Stats aggregation:
/api/evidence/statsgroups evidence bychunkingStatus(PENDING,PROCESSING,COMPLETED,FAILED,SKIPPED) and always returns zero values for missing buckets.
2. Upload Flow¶
- Permitted uploaders: Only the assigned auditor or the owning customer (including demo mode) may upload evidence; managers and admins are explicitly excluded to preserve audit integrity.
- Tag handling:
- Explicit
tagsfrom the client are upserted viaprisma.tag.upsert. - Tags inherited from linked controls (via
projectControl→control.tags) are merged into the final set. - Control links: The request may supply
controlIdsthat correspond toprojectControlrecords; the backend connects the evidence to those controls and recalculates counts perrecalcEvidenceCounts. - Chunking metadata: Evidence starts with
chunkingStatus = 'PENDING'and, if URL-based,isUrlBased/downloadStatustoggles so workers know to fetch and chunk it before it becomes search-visible. - Graph events: After creation, the code enqueues Neo4j events for:
linkEvidenceToTaglinkEvidenceUploaderlinkEvidenceToProjectlinkEvidenceToControl- (Additional tag/control associations are also re-emitted during updates; see
GraphServicefor the full event catalog.)
3. Update, Delete, Refresh¶
- Updates:
PUT /api/evidence/:idlets auditors (for their project) and the uploader (customer) change filenames, controls, and tags. Tag sets are re-derived with the same upsert logic, and linked controls triggerrecalcEvidenceCounts. - Delete guards: Evidence may only be deleted by the auditor (or uploader when the auditor uploaded it) or the owning customer, and only if the parent project is not in
review_pending,completed, orapprovedstatus. - Refresh:
POST /api/evidence/:id/refreshre-triggers downloads but only forisUrlBasedevidence; auditors, the uploader, or managers may hit this endpoint. It resetsdownloadStatus/chunkingStatustoPENDINGso the worker retries.
4. Annotations & AI Evaluation¶
- Annotations:
- Both
GET /:id/annotationsandPOST /:id/annotationsapply the same role logic (manager, auditor/reviewer, customer, shared user). - Creating an annotation requires
textand coordinates (x,y), optionally notifying the customer; the code logs the intent even though no email sending is implemented. - Responses return author details (
id,name,role) for UI rendering. - AI analysis:
POST /api/evidence/:id/analyzedelegates toAnalysisService.analyzeEvidence. - The service fetches evidence + linked controls, concatenates document chunks, prompts Gemini (
gemini-1.5-flash), and parses the JSON result. - The parsed evaluation is stored in
evidence.evaluationResultand includes per-control statuses (pass/fail/partial/not_applicable).
5. Graph Synchronization¶
- Event queue:
GraphServiceenqueues jobs intoneo4jSyncQueueto keep Neo4j in sync. Key events used by evidence flows includelinkEvidenceToProject,linkEvidenceToControl,linkEvidenceToTag, andlinkEvidenceUploader, but the service also supports linking auditors, managers, controls, and standards. - Eventual consistency: Graph updates happen asynchronously; frontend features should not assume immediate graph reflections. Monitoring the queue/logs is the reliable way to detect failures.
6. Observability & Auditing¶
- Debug logging: The routes log key steps (tag resolution, graph operations, permission checks) to help operators trace difficult uploads.
- Recalculation hooks:
recalcEvidenceCountsrecomputes eachProjectControl’s evidence count before responding, keeping the control dashboards accurate.