{"openapi":"3.0.3","info":{"title":"ITWC IRB System API","version":"1.0.0","description":"# ITWC IRB System API\n\nThe ITWC IRB (Institutional Review Board) System provides a comprehensive API\nfor managing clinical research studies, IRB submissions, regulatory compliance,\nparticipant consent, adverse event reporting, FDA submissions, and more.\n\n## Authentication\n\nAll endpoints (except `/api/health`) require authentication via one of:\n\n- **Bearer Token**: Include `Authorization: Bearer <token>` in request headers\n- **Session Cookie**: Use NextAuth.js session-based authentication via browser\n\n## Rate Limiting\n\n- Standard tier: 100 requests per minute\n- Enterprise tier: 1,000 requests per minute\n\nRate limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`)\nare included in all responses.\n\n## RBAC (Role-Based Access Control)\n\nAccess is controlled by user roles: `SUPER_ADMIN`, `ADMIN`, `PI`,\n`COORDINATOR`, `REVIEWER`, `CLINICIAN`, `SPONSOR`, `REGULATORY_AFFAIRS`, `MEMBER`.\n\nPermissions are checked at both the role level (`hasPermission`) and the\nresource level (`canAccessResource`) based on organization membership.\n\n## Pagination\n\nList endpoints support `limit` (page size, max 100) and `offset` parameters.\nResponses include a `pagination` object with `total`, `limit`, `offset`, and `hasMore`.\n\n## Audit Logging\n\nAll data-modifying operations create audit log entries with user ID, IP address,\nuser agent, and the action performed.","contact":{"name":"ITWC Engineering","email":"api-support@sova.health"},"license":{"name":"Proprietary"}},"servers":[{"url":"http://localhost:3003","description":"Local development"},{"url":"https://irb.sova.health","description":"Production"}],"tags":[{"name":"Health","description":"Service health checks and readiness probes"},{"name":"Auth","description":"Authentication and session management"},{"name":"Studies","description":"Research study CRUD, fidelity monitoring, and data quality"},{"name":"Participants","description":"Participant visits and consent tracking"},{"name":"Consent","description":"Informed consent signing and audit trail"},{"name":"Adverse Events","description":"Adverse event reporting and tracking"},{"name":"Submissions","description":"IRB submission workflow management"},{"name":"FDA","description":"FDA applications (IND/IDE/NDA/BLA) and safety reports"},{"name":"Regulatory","description":"Regulatory submissions overview and timeline"},{"name":"Compliance","description":"Compliance status checks, alerts, and enforcement"},{"name":"PKI","description":"21 CFR Part 11 digital signatures and verification"},{"name":"Meetings","description":"IRB meeting scheduling, attendance, and votes"},{"name":"Budgets","description":"Study budget management, line items, and allocations"},{"name":"Notifications","description":"User notification management"},{"name":"FHIR","description":"FHIR R4 webhook integration for real-time sync"},{"name":"Monitoring","description":"Risk-based monitoring and data quality metrics"},{"name":"Video Consent","description":"On-camera e-consent sessions with recording, 21 CFR Part 11 compliance, and cross-portal integration"}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token obtained from the authentication endpoint or API key generated from organization settings."},"SessionAuth":{"type":"apiKey","in":"cookie","name":"next-auth.session-token","description":"NextAuth.js session cookie set after browser-based authentication."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"]},"ValidationError":{"type":"object","properties":{"error":{"type":"string","example":"Validation error"},"details":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"path":{"type":"array","items":{"type":"string"}}}}}},"required":["error","details"]},"Pagination":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of records"},"limit":{"type":"integer","description":"Page size"},"offset":{"type":"integer","description":"Current offset"},"hasMore":{"type":"boolean","description":"Whether more records exist"}},"required":["total","limit","offset","hasMore"]},"UserRef":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email"}}},"OrgRef":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"name":{"type":"string"},"type":{"type":"string","enum":["IRB","SPONSOR","CRO","SITE","ACADEMIC","GOVERNMENT","OTHER"]}}},"StudyStatus":{"type":"string","enum":["DRAFT","SUBMITTED","UNDER_REVIEW","APPROVED","ACTIVE","COMPLETED","SUSPENDED","TERMINATED"]},"StudyPhase":{"type":"string","enum":["PHASE_I","PHASE_II","PHASE_III","PHASE_IV","NA","PILOT"]},"Study":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"key":{"type":"string","example":"STUDY-001"},"title":{"type":"string","example":"Phase III Randomized Controlled Trial"},"status":{"$ref":"#/components/schemas/StudyStatus"},"protocol":{"type":"string"},"protocolVersion":{"type":"string","nullable":true},"irbOfRecord":{"type":"string","nullable":true},"orgId":{"type":"string","format":"cuid"},"piId":{"type":"string","format":"cuid","nullable":true},"description":{"type":"string","nullable":true},"startDate":{"type":"string","format":"date-time","nullable":true},"endDate":{"type":"string","format":"date-time","nullable":true},"enrollmentGoal":{"type":"integer","nullable":true},"phase":{"$ref":"#/components/schemas/StudyPhase"},"therapeuticArea":{"type":"string","nullable":true},"sponsor":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"pi":{"$ref":"#/components/schemas/UserRef"},"org":{"$ref":"#/components/schemas/OrgRef"},"_count":{"type":"object","properties":{"submissions":{"type":"integer"},"consents":{"type":"integer"},"events":{"type":"integer"}}}}},"CreateStudyRequest":{"type":"object","required":["key","title","protocol"],"properties":{"key":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[a-zA-Z0-9-_]+$","example":"STUDY-001","description":"Unique alphanumeric study key"},"title":{"type":"string","minLength":1,"maxLength":500,"example":"Phase III RCT for Novel Therapeutic"},"description":{"type":"string"},"protocol":{"type":"string","minLength":1},"irbOfRecord":{"type":"string"},"startDate":{"type":"string","format":"date-time"},"enrollmentGoal":{"type":"integer","minimum":1}}},"UpdateStudyRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500},"description":{"type":"string"},"protocol":{"type":"string","minLength":1},"status":{"$ref":"#/components/schemas/StudyStatus"},"irbOfRecord":{"type":"string"},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"},"enrollmentGoal":{"type":"integer","minimum":1},"currentStatus":{"type":"string"}}},"SubmissionType":{"type":"string","enum":["INITIAL","CONTINUING_REVIEW","AMENDMENT","REPORTABLE_EVENT","STUDY_CLOSURE","CONSENT_UPDATE"]},"SubmissionState":{"type":"string","enum":["RECEIVED","PRE_REVIEW","ASSIGNED","UNDER_REVIEW","REVISIONS_REQUESTED","APPROVED","REJECTED","WITHDRAWN","TABLED"]},"Submission":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"studyId":{"type":"string","format":"cuid"},"type":{"$ref":"#/components/schemas/SubmissionType"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"state":{"$ref":"#/components/schemas/SubmissionState"},"priority":{"type":"string","enum":["LOW","NORMAL","HIGH","URGENT"]},"payload":{"type":"object"},"dueDate":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"study":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"title":{"type":"string"}}},"submitter":{"$ref":"#/components/schemas/UserRef"},"assignedTo":{"$ref":"#/components/schemas/UserRef"}}},"CreateSubmissionRequest":{"type":"object","required":["studyId","type","title","payload"],"properties":{"studyId":{"type":"string","format":"cuid"},"type":{"$ref":"#/components/schemas/SubmissionType"},"title":{"type":"string","minLength":1,"maxLength":500},"description":{"type":"string"},"payload":{"type":"object","description":"Submission-type-specific data"},"priority":{"type":"string","enum":["LOW","NORMAL","HIGH","URGENT"],"default":"NORMAL"},"dueDate":{"type":"string","format":"date-time"}}},"AdverseEvent":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"studyId":{"type":"string"},"clinicSiteId":{"type":"string","nullable":true},"participantCode":{"type":"string","nullable":true},"eventDate":{"type":"string","format":"date-time"},"reportDate":{"type":"string","format":"date-time"},"category":{"type":"string","enum":["MILD","MODERATE","SEVERE","LIFE_THREATENING","DEATH"]},"severity":{"type":"string","enum":["GRADE_1","GRADE_2","GRADE_3","GRADE_4","GRADE_5"]},"relationship":{"type":"string","enum":["UNRELATED","UNLIKELY","POSSIBLE","PROBABLE","DEFINITE","UNKNOWN"]},"description":{"type":"string"},"outcome":{"type":"string","nullable":true},"actionTaken":{"type":"string","nullable":true},"isSerious":{"type":"boolean"},"isSuspected":{"type":"boolean"},"reportedBy":{"type":"string","nullable":true},"status":{"type":"string","enum":["OPEN","UNDER_INVESTIGATION","RESOLVED","CLOSED"]},"study":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"title":{"type":"string"}}},"clinicSite":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"}}}}},"CreateAdverseEventRequest":{"type":"object","required":["studyId","eventDate","category","severity","description"],"properties":{"studyId":{"type":"string"},"clinicSiteId":{"type":"string"},"participantCode":{"type":"string"},"eventDate":{"type":"string","format":"date-time"},"category":{"type":"string","enum":["MILD","MODERATE","SEVERE","LIFE_THREATENING","DEATH"]},"severity":{"type":"string","enum":["GRADE_1","GRADE_2","GRADE_3","GRADE_4","GRADE_5"]},"relationship":{"type":"string","enum":["UNRELATED","UNLIKELY","POSSIBLE","PROBABLE","DEFINITE","UNKNOWN"],"default":"UNKNOWN"},"description":{"type":"string","minLength":10},"outcome":{"type":"string"},"actionTaken":{"type":"string"},"isSerious":{"type":"boolean","default":false},"isSuspected":{"type":"boolean","default":false},"reportedBy":{"type":"string"},"reporterRole":{"type":"string"}}},"SignConsentRequest":{"type":"object","required":["participantId","signedByName"],"properties":{"participantId":{"type":"string","minLength":1},"signatureType":{"type":"string","enum":["PARTICIPANT","LEGALLY_AUTHORIZED_REPRESENTATIVE","WITNESS","INVESTIGATOR"],"default":"PARTICIPANT"},"signatureMethod":{"type":"string","enum":["TYPED","DRAWN","UPLOADED","BIOMETRIC"],"default":"TYPED"},"signatureData":{"type":"string","description":"Base64 encoded signature or typed name"},"signedByName":{"type":"string","minLength":1},"witnessName":{"type":"string"},"witnessSignature":{"type":"string"},"previousSignatureId":{"type":"string","description":"For re-consent flow"}}},"ConsentSignature":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"consentId":{"type":"string"},"participantId":{"type":"string"},"signatureType":{"type":"string"},"signatureMethod":{"type":"string"},"signedByName":{"type":"string"},"signedAt":{"type":"string","format":"date-time"},"ipAddress":{"type":"string"},"participant":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"mrn":{"type":"string"}}}}},"FDAApplication":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"studyId":{"type":"string"},"applicationType":{"type":"string","enum":["IND","IDE","NDA","BLA","ANDA","PMA","PMN_510K"]},"applicationNumber":{"type":"string","nullable":true},"sponsorName":{"type":"string"},"status":{"type":"string","enum":["PREPARATION","SUBMITTED","ACKNOWLEDGED","UNDER_REVIEW","CLINICAL_HOLD","ACTIVE","APPROVED","WITHDRAWN","REFUSED_TO_FILE","COMPLETE_RESPONSE"]},"fastTrackDesignation":{"type":"boolean"},"breakthroughTherapy":{"type":"boolean"},"acceleratedApproval":{"type":"boolean"},"priorityReview":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"study":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"title":{"type":"string"},"phase":{"type":"string","nullable":true},"sponsor":{"type":"string","nullable":true}}},"stats":{"type":"object","properties":{"submissionCount":{"type":"integer"},"correspondenceCount":{"type":"integer"},"safetyReportCount":{"type":"integer"},"isActive":{"type":"boolean"},"isOnHold":{"type":"boolean"},"hasDesignations":{"type":"boolean"}}}}},"CreateFDAApplicationRequest":{"type":"object","required":["studyId","applicationType","sponsorName"],"properties":{"studyId":{"type":"string","format":"cuid"},"applicationType":{"type":"string","enum":["IND","IDE","NDA","BLA","ANDA","PMA","PMN_510K"]},"applicationNumber":{"type":"string"},"sponsorName":{"type":"string","minLength":1},"sponsorContact":{"type":"string"},"sponsorEmail":{"type":"string","format":"email"},"fdaDivision":{"type":"string"},"fastTrackDesignation":{"type":"boolean","default":false},"breakthroughTherapy":{"type":"boolean","default":false},"acceleratedApproval":{"type":"boolean","default":false},"priorityReview":{"type":"boolean","default":false},"preIndMeetingDate":{"type":"string","format":"date-time"},"notes":{"type":"string"}}},"SafetyReport":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"applicationId":{"type":"string"},"studyId":{"type":"string"},"reportType":{"type":"string","enum":["IND_SAFETY","IDE_SAFETY","MEDWATCH_3500A","CIOMS_I","DSUR","SUSAR"]},"eventDate":{"type":"string","format":"date-time"},"severity":{"type":"string","enum":["MILD","MODERATE","SEVERE","LIFE_THREATENING","DEATH"]},"eventTerm":{"type":"string"},"eventDescription":{"type":"string"},"status":{"type":"string"},"regulatoryDeadline":{"type":"string","format":"date-time"},"deadlineType":{"type":"string","enum":["SEVEN_DAY","FIFTEEN_DAY"]},"isOverdue":{"type":"boolean"},"calculatedDaysRemaining":{"type":"integer"},"deadlineUrgency":{"type":"string","enum":["OVERDUE","CRITICAL","URGENT","WARNING","NORMAL"]}}},"CreateSafetyReportRequest":{"type":"object","required":["applicationId","studyId","reportType","eventDate","severity","eventTerm","eventDescription"],"properties":{"applicationId":{"type":"string","format":"cuid"},"studyId":{"type":"string","format":"cuid"},"reportType":{"type":"string","enum":["IND_SAFETY","IDE_SAFETY","MEDWATCH_3500A","CIOMS_I","DSUR","SUSAR"]},"eventDate":{"type":"string","format":"date-time"},"subjectId":{"type":"string"},"siteId":{"type":"string"},"isSeriousAdverseEvent":{"type":"boolean","default":true},"isUnexpected":{"type":"boolean","default":false},"isRelatedToStudyDrug":{"type":"boolean"},"relatednessAssessment":{"type":"string"},"severity":{"type":"string","enum":["MILD","MODERATE","SEVERE","LIFE_THREATENING","DEATH"]},"outcome":{"type":"string","enum":["RECOVERED","RECOVERING","NOT_RECOVERED","RECOVERED_WITH_SEQUELAE","FATAL","UNKNOWN"]},"eventTerm":{"type":"string","minLength":1},"meddraCode":{"type":"string"},"eventDescription":{"type":"string","minLength":1},"narrativeSummary":{"type":"string"},"isFollowUp":{"type":"boolean","default":false},"originalReportId":{"type":"string","format":"cuid"},"notes":{"type":"string"}}},"Meeting":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"title":{"type":"string"},"type":{"type":"string","enum":["CONVENED","EXPEDITED","EXEMPT","EMERGENCY","SPECIAL"]},"scheduledAt":{"type":"string","format":"date-time"},"duration":{"type":"integer","description":"Duration in minutes"},"location":{"type":"string","nullable":true},"virtualLink":{"type":"string","nullable":true},"agenda":{"type":"string","nullable":true},"status":{"type":"string","enum":["SCHEDULED","IN_PROGRESS","COMPLETED","CANCELLED"]},"organizer":{"$ref":"#/components/schemas/UserRef"},"_count":{"type":"object","properties":{"attendees":{"type":"integer"}}}}},"CreateMeetingRequest":{"type":"object","required":["title","type","scheduledAt"],"properties":{"title":{"type":"string"},"type":{"type":"string","enum":["CONVENED","EXPEDITED","EXEMPT","EMERGENCY","SPECIAL"]},"scheduledAt":{"type":"string","format":"date-time"},"duration":{"type":"integer","default":60},"location":{"type":"string"},"virtualLink":{"type":"string"},"agenda":{"type":"string"},"notes":{"type":"string"},"studyIds":{"type":"array","items":{"type":"string"}}}},"Budget":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"studyId":{"type":"string"},"name":{"type":"string"},"totalAmount":{"type":"number"},"currency":{"type":"string","example":"USD"},"status":{"type":"string","enum":["DRAFT","PENDING_APPROVAL","APPROVED","ACTIVE","CLOSED","AMENDED"]},"lineItems":{"type":"array","items":{"type":"object"}},"siteAllocations":{"type":"array","items":{"type":"object"}},"summary":{"type":"object","properties":{"totalLineItems":{"type":"number"},"totalAllocated":{"type":"number"},"totalSpent":{"type":"number"},"remaining":{"type":"number"},"unallocated":{"type":"number"},"utilizationPercent":{"type":"integer"}}}}},"UpdateBudgetRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"totalAmount":{"type":"number","minimum":0},"currency":{"type":"string","minLength":3,"maxLength":3},"status":{"type":"string","enum":["DRAFT","PENDING_APPROVAL","APPROVED","ACTIVE","CLOSED","AMENDED"]},"effectiveDate":{"type":"string","format":"date-time","nullable":true},"expirationDate":{"type":"string","format":"date-time","nullable":true},"notes":{"type":"string","nullable":true}}},"SignRequest":{"type":"object","required":["certificateId","privateKeyPem","resourceType","resourceId","documentContent"],"properties":{"certificateId":{"type":"string"},"privateKeyPem":{"type":"string","description":"PEM-encoded private key"},"resourceType":{"type":"string"},"resourceId":{"type":"string"},"documentContent":{"type":"string"},"purpose":{"type":"string","enum":["ATTESTATION","APPROVAL","WITNESSING","ACKNOWLEDGMENT","AUTHORIZATION","CONSENT"],"default":"ATTESTATION"},"addTimestamp":{"type":"boolean","default":true}}},"SignatureResult":{"type":"object","properties":{"success":{"type":"boolean"},"signature":{"type":"object","properties":{"id":{"type":"string"},"documentHash":{"type":"string"},"signatureValue":{"type":"string"},"algorithm":{"type":"string"},"signedAt":{"type":"string","format":"date-time"},"hasTimestamp":{"type":"boolean"},"timestampedAt":{"type":"string","format":"date-time","nullable":true},"timestampAuthority":{"type":"string","nullable":true}}}}},"VerifyRequest":{"type":"object","required":["documentContent"],"properties":{"documentContent":{"type":"string","description":"The document content to verify the signature against"}}},"VerificationResult":{"type":"object","properties":{"success":{"type":"boolean"},"verification":{"type":"object","properties":{"isValid":{"type":"boolean"},"documentHashMatch":{"type":"boolean"},"signatureValid":{"type":"boolean"},"certificateValid":{"type":"boolean"},"timestampValid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"signedAt":{"type":"string","format":"date-time"},"signer":{"type":"object"}}}}},"ComplianceStatus":{"type":"object","properties":{"success":{"type":"boolean"},"status":{"type":"object","properties":{"canEnroll":{"type":"boolean"},"canSign":{"type":"boolean"},"blockingIssues":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object"}},"upcomingDeadlines":{"type":"array","items":{"type":"object"}}}},"summary":{"type":"object","properties":{"canEnroll":{"type":"boolean"},"canSign":{"type":"boolean"},"blockingIssueCount":{"type":"integer"},"warningCount":{"type":"integer"},"upcomingDeadlineCount":{"type":"integer"},"criticalDeadlines":{"type":"integer"}}}}},"ComplianceAlert":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"alertType":{"type":"string"},"severity":{"type":"string","enum":["CRITICAL","URGENT","WARNING","INFO"]},"status":{"type":"string","enum":["PENDING","ACKNOWLEDGED","RESOLVED","DISMISSED"]},"message":{"type":"string"},"escalationLevel":{"type":"integer"},"study":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"title":{"type":"string"}}},"user":{"$ref":"#/components/schemas/UserRef"}}},"BulkAcknowledgeRequest":{"type":"object","required":["action","alertIds"],"properties":{"action":{"type":"string","enum":["acknowledge"]},"alertIds":{"type":"array","items":{"type":"string","format":"cuid"},"minItems":1},"notes":{"type":"string"}}},"Notification":{"type":"object","properties":{"id":{"type":"string","format":"cuid"},"userId":{"type":"string"},"type":{"type":"string"},"category":{"type":"string"},"title":{"type":"string"},"message":{"type":"string"},"link":{"type":"string","nullable":true},"isRead":{"type":"boolean"},"isDismissed":{"type":"boolean"},"priority":{"type":"string","enum":["LOW","NORMAL","HIGH","URGENT"]},"createdAt":{"type":"string","format":"date-time"}}},"FHIRWebhookPayload":{"type":"object","required":["id","resourceType"],"properties":{"id":{"type":"string","description":"FHIR resource ID"},"resourceType":{"type":"string","description":"FHIR resource type","enum":["ResearchStudy","ResearchSubject","AdverseEvent","Consent"]},"meta":{"type":"object","properties":{"versionId":{"type":"string"},"lastUpdated":{"type":"string","format":"date-time"}}}}},"HealthCheckResponse":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"]},"timestamp":{"type":"string","format":"date-time"},"version":{"type":"string"},"uptime":{"type":"integer","description":"Uptime in seconds"},"services":{"type":"object","properties":{"database":{"type":"string","enum":["connected","disconnected","degraded"]},"application":{"type":"string","enum":["running","starting","stopping"]}}},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["pass","fail","warn"]},"duration":{"type":"number"},"message":{"type":"string"}}}}}},"ScheduleVisitRequest":{"type":"object","required":["visitNumber","visitName","scheduledDate"],"properties":{"visitTemplateId":{"type":"string"},"visitNumber":{"type":"integer","minimum":0},"visitName":{"type":"string","minLength":1},"scheduledDate":{"type":"string","format":"date-time"},"scheduledTime":{"type":"string"},"clinicSiteId":{"type":"string"},"notes":{"type":"string"}}},"RegulatorySubmission":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"number":{"type":"string"},"studyId":{"type":"string"},"studyTitle":{"type":"string"},"agency":{"type":"string"},"status":{"type":"string"},"submissionDate":{"type":"string","format":"date","nullable":true},"approvalDate":{"type":"string","format":"date","nullable":true},"lastUpdate":{"type":"string","format":"date"},"amendments":{"type":"integer"},"safetyReports":{"type":"integer"}}},"TimelineEvent":{"type":"object","properties":{"id":{"type":"string"},"date":{"type":"string","format":"date"},"type":{"type":"string","enum":["DEADLINE","SUBMISSION","RESPONSE"]},"title":{"type":"string"},"description":{"type":"string"},"submission":{"type":"string"},"agency":{"type":"string"},"status":{"type":"string","enum":["UPCOMING","COMPLETED","OVERDUE","PLANNED","SCHEDULED","EXPECTED"]},"isDeadline":{"type":"boolean"}}}}},"paths":{"/api/health":{"get":{"tags":["Health"],"operationId":"getHealth","summary":"Health check","description":"Returns service health status including database connectivity, memory usage, and uptime. Used by load balancers and monitoring systems. No authentication required.","responses":{"200":{"description":"Service is healthy or degraded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthCheckResponse"}}}},"503":{"description":"Service is unhealthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthCheckResponse"}}}}}}},"/api/studies":{"get":{"tags":["Studies"],"operationId":"listStudies","summary":"List studies","description":"Returns a paginated list of studies belonging to the authenticated user's organization. Supports filtering by status.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/StudyStatus"},"description":"Filter by study status"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"minimum":1,"maximum":100},"description":"Page size (max 100)"},{"name":"offset","in":"query","schema":{"type":"integer","default":0,"minimum":0},"description":"Pagination offset"}],"responses":{"200":{"description":"List of studies with pagination","content":{"application/json":{"schema":{"type":"object","properties":{"studies":{"type":"array","items":{"$ref":"#/components/schemas/Study"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"example":{"studies":[{"id":"cm1abc123def456","key":"ONCO-2025-001","title":"Phase III Randomized Controlled Trial for Novel Immunotherapy","status":"ACTIVE","protocol":"ONCO-2025-001-PROTOCOL","pi":{"id":"cm1user123","name":"Dr. Jane Smith","email":"jane.smith@example.org"},"org":{"id":"cm1org123","name":"Academic Medical Center","type":"ACADEMIC"},"_count":{"submissions":5,"consents":3,"events":12}}],"pagination":{"total":24,"limit":50,"offset":0,"hasMore":false}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Studies"],"operationId":"createStudy","summary":"Create a new study","description":"Creates a new study in DRAFT status. The authenticated user is automatically assigned as the Principal Investigator. The study key must be unique.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStudyRequest"}}}},"responses":{"201":{"description":"Study created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Study"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Study key already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/studies/{id}":{"get":{"tags":["Studies"],"operationId":"getStudy","summary":"Get study details","description":"Returns detailed study information including PI, organization, consents, recent submissions, events, and files. Resource-level access control is enforced.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Study ID"}],"responses":{"200":{"description":"Study details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Study"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Study not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Studies"],"operationId":"updateStudy","summary":"Update a study","description":"Partially updates study fields. When the status field is changed, a webhook notification is emitted to integrated systems.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Study ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStudyRequest"}}}},"responses":{"200":{"description":"Updated study","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Study"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Study not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/studies/{id}/fidelity":{"get":{"tags":["Studies","Monitoring"],"operationId":"getStudyFidelity","summary":"Get study fidelity data","description":"Returns fidelity ratings, therapist performance metrics, protocol component adherence, training needs, and aggregate metrics for a study.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Study ID"}],"responses":{"200":{"description":"Fidelity data","content":{"application/json":{"schema":{"type":"object","properties":{"reviews":{"type":"array","items":{"type":"object"}},"therapists":{"type":"array","items":{"type":"object"}},"protocolComponents":{"type":"array","items":{"type":"object"}},"trainingNeeds":{"type":"array","items":{"type":"object"}},"metrics":{"type":"object","properties":{"totalReviews":{"type":"integer"},"reviewsThisMonth":{"type":"integer"},"averageAdherence":{"type":"integer"},"averageCompetence":{"type":"integer"},"therapistsAboveThreshold":{"type":"integer"},"totalTherapists":{"type":"integer"},"pendingTrainings":{"type":"integer"},"protocolDeviationRate":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Study not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/studies/{id}/data-quality":{"get":{"tags":["Studies","Monitoring"],"operationId":"getStudyDataQuality","summary":"Get study data quality metrics","description":"Returns data quality metrics and completeness scores for all participants in a study.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Study ID"}],"responses":{"200":{"description":"Data quality metrics","content":{"application/json":{"schema":{"type":"object","properties":{"metrics":{"type":"object","description":"Data quality metrics"},"studyAverage":{"type":"number","description":"Average completeness score"},"participantScores":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/participants/{id}/visits":{"get":{"tags":["Participants"],"operationId":"getParticipantVisits","summary":"Get participant visit schedule","description":"Returns the participant's visit schedule including templates, actual visits, window calculations, and summary statistics.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Participant ID"}],"responses":{"200":{"description":"Visit schedule and statistics","content":{"application/json":{"schema":{"type":"object","properties":{"participant":{"type":"object"},"study":{"type":"object"},"visitSchedule":{"type":"array","items":{"type":"object"}},"visits":{"type":"array","items":{"type":"object"}},"stats":{"type":"object","properties":{"totalVisits":{"type":"integer"},"completed":{"type":"integer"},"scheduled":{"type":"integer"},"missed":{"type":"integer"},"due":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Participant not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Participants"],"operationId":"scheduleVisit","summary":"Schedule a visit for a participant","description":"Creates a new visit record for a participant. If a visit template is provided, window calculations are performed automatically.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Participant ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleVisitRequest"}}}},"responses":{"201":{"description":"Visit scheduled","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"404":{"description":"Participant not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/participants/{id}/consents":{"get":{"tags":["Participants","Consent"],"operationId":"getParticipantConsents","summary":"Get participant consent history","description":"Returns the participant's consent status across all active study consents, including signature details, expiration tracking, and a summary of required actions.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Participant ID"}],"responses":{"200":{"description":"Consent history and status","content":{"application/json":{"schema":{"type":"object","properties":{"participant":{"type":"object"},"study":{"type":"object"},"consentStatus":{"type":"array","items":{"type":"object"}},"signatures":{"type":"array","items":{"$ref":"#/components/schemas/ConsentSignature"}},"summary":{"type":"object","properties":{"totalConsents":{"type":"integer"},"signed":{"type":"integer"},"expired":{"type":"integer"},"pendingWitness":{"type":"integer"},"notSigned":{"type":"integer"},"requiresAction":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Participant not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/consents/{id}/sign":{"post":{"tags":["Consent"],"operationId":"signConsent","summary":"Sign a consent form","description":"Records a signature on a consent form for a participant. Supports participant, LAR, witness, and investigator signature types. Creates an audit trail and updates the participant consent status. Witness signature is required when the consent has witnessRequired=true.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Consent ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignConsentRequest"}}}},"responses":{"201":{"description":"Consent signed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"signature":{"$ref":"#/components/schemas/ConsentSignature"},"message":{"type":"string"}}}}}},"400":{"description":"Validation error or consent not active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Consent or participant not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/adverse-events":{"get":{"tags":["Adverse Events"],"operationId":"listAdverseEvents","summary":"List adverse events","description":"Returns a paginated list of adverse events with filtering by study, clinic, severity, seriousness, and status. Includes per-status aggregate counts.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"studyId","in":"query","schema":{"type":"string"},"description":"Filter by study ID"},{"name":"clinicSiteId","in":"query","schema":{"type":"string"},"description":"Filter by clinic site ID"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by AE status"},{"name":"isSerious","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Filter serious events"},{"name":"category","in":"query","schema":{"type":"string"},"description":"Filter by category"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Adverse events with statistics","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AdverseEvent"}},"stats":{"type":"object","additionalProperties":{"type":"integer"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Adverse Events"],"operationId":"reportAdverseEvent","summary":"Report a new adverse event","description":"Reports a new adverse event for a study. Also creates a corresponding StudyEvent record for the event timeline. Can be called by clinics via API.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAdverseEventRequest"}}}},"responses":{"201":{"description":"Adverse event reported","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdverseEvent"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"404":{"description":"Study or clinic site not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/submissions":{"get":{"tags":["Submissions"],"operationId":"listSubmissions","summary":"List IRB submissions","description":"Returns paginated IRB submissions. Supports filtering by workflow state, study, and assignment. Includes related study, submitter, and assignee data.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"state","in":"query","schema":{"$ref":"#/components/schemas/SubmissionState"},"description":"Filter by workflow state"},{"name":"studyId","in":"query","schema":{"type":"string"},"description":"Filter by study"},{"name":"assignedToMe","in":"query","schema":{"type":"string","enum":["true"]},"description":"Show only my assignments"},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Submissions with pagination","content":{"application/json":{"schema":{"type":"object","properties":{"submissions":{"type":"array","items":{"$ref":"#/components/schemas/Submission"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Submissions"],"operationId":"createSubmission","summary":"Create a new IRB submission","description":"Creates a new IRB submission in the RECEIVED state. Validates that the referenced study exists and belongs to the user's organization.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubmissionRequest"}}}},"responses":{"201":{"description":"Submission created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Submission"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"404":{"description":"Study not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fda/applications":{"get":{"tags":["FDA"],"operationId":"listFDAApplications","summary":"List FDA applications","description":"Lists FDA applications (IND/IDE/NDA/BLA/etc.) with filtering by study, type, and status. Includes submission, correspondence, and safety report counts.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"studyId","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string","enum":["IND","IDE","NDA","BLA","ANDA","PMA","PMN_510K"]}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"FDA applications","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"applications":{"type":"array","items":{"$ref":"#/components/schemas/FDAApplication"}},"total":{"type":"integer"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["FDA"],"operationId":"createFDAApplication","summary":"Create a new FDA application","description":"Creates a new FDA application (IND, IDE, NDA, BLA, etc.) in PREPARATION status. Requires ADMIN, REGULATORY_AFFAIRS, or SPONSOR role. Only one application type per study is allowed.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFDAApplicationRequest"}}}},"responses":{"200":{"description":"FDA application created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"application":{"$ref":"#/components/schemas/FDAApplication"}}}}}},"400":{"description":"Validation error or duplicate application type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Regulatory Affairs access required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Study not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/fda/safety-reports":{"get":{"tags":["FDA"],"operationId":"listSafetyReports","summary":"List FDA safety reports","description":"Lists safety reports with real-time deadline tracking. Includes overdue calculations, urgency levels, and summary statistics.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"applicationId","in":"query","schema":{"type":"string"}},{"name":"studyId","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"overdue","in":"query","schema":{"type":"string","enum":["true"]},"description":"Show only overdue reports"},{"name":"deadlineType","in":"query","schema":{"type":"string","enum":["SEVEN_DAY","FIFTEEN_DAY"]}}],"responses":{"200":{"description":"Safety reports with deadline status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"reports":{"type":"array","items":{"$ref":"#/components/schemas/SafetyReport"}},"stats":{"type":"object","properties":{"total":{"type":"integer"},"overdue":{"type":"integer"},"critical":{"type":"integer"},"pending":{"type":"integer"},"sevenDay":{"type":"integer"},"fifteenDay":{"type":"integer"}}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["FDA"],"operationId":"createSafetyReport","summary":"Create a new safety report","description":"Creates a new FDA safety report with automatic regulatory deadline calculation. Fatal or life-threatening events receive a 7-day deadline; all others receive 15-day deadlines.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSafetyReportRequest"}}}},"responses":{"200":{"description":"Safety report created with deadline info","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"report":{"$ref":"#/components/schemas/SafetyReport"},"deadline":{"type":"object","properties":{"date":{"type":"string","format":"date-time"},"type":{"type":"string"},"daysRemaining":{"type":"integer"},"isOverdue":{"type":"boolean"},"urgency":{"type":"string"}}},"message":{"type":"string"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"404":{"description":"FDA application not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/regulatory/submissions":{"get":{"tags":["Regulatory"],"operationId":"listRegulatorySubmissions","summary":"List regulatory submissions","description":"Returns a unified view of all regulatory submissions across FDA applications, mapped to a standard format with status, dates, and counts.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"agency","in":"query","schema":{"type":"string"},"description":"Filter by agency (e.g., FDA)"},{"name":"type","in":"query","schema":{"type":"string"},"description":"Filter by application type"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by status"}],"responses":{"200":{"description":"Regulatory submissions","content":{"application/json":{"schema":{"type":"object","properties":{"submissions":{"type":"array","items":{"$ref":"#/components/schemas/RegulatorySubmission"}},"total":{"type":"integer"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/regulatory/timeline":{"get":{"tags":["Regulatory"],"operationId":"getRegulatoryTimeline","summary":"Get regulatory timeline","description":"Returns a chronological timeline of regulatory events including deadlines and FDA submissions, with upcoming deadline tracking and priority calculations.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"studyId","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Timeline events and deadlines","content":{"application/json":{"schema":{"type":"object","properties":{"timelineEvents":{"type":"array","items":{"$ref":"#/components/schemas/TimelineEvent"}},"deadlines":{"type":"array","items":{"$ref":"#/components/schemas/TimelineEvent"}},"total":{"type":"integer"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/compliance/status":{"get":{"tags":["Compliance"],"operationId":"getComplianceStatus","summary":"Check compliance status","description":"Checks whether a user can enroll participants and sign documents. Returns blocking issues, warnings, and upcoming deadlines. Non-admins can only check their own status.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"userId","in":"query","schema":{"type":"string"},"description":"User ID (defaults to current user)"},{"name":"studyId","in":"query","schema":{"type":"string"},"description":"Scope to a specific study"}],"responses":{"200":{"description":"Compliance status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceStatus"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden - can only check own status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/compliance/alerts":{"get":{"tags":["Compliance"],"operationId":"listComplianceAlerts","summary":"List compliance alerts","description":"Lists compliance alerts with rich filtering options. Returns alerts sorted by status (pending first), severity, and escalation level. Includes summary statistics.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"studyId","in":"query","schema":{"type":"string"}},{"name":"userId","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["PENDING","ACKNOWLEDGED","RESOLVED","DISMISSED"]}},{"name":"severity","in":"query","schema":{"type":"string","enum":["CRITICAL","URGENT","WARNING","INFO"]}},{"name":"alertType","in":"query","schema":{"type":"string"}},{"name":"pendingOnly","in":"query","schema":{"type":"string","enum":["true"]}},{"name":"escalatedOnly","in":"query","schema":{"type":"string","enum":["true"]}},{"name":"myAlerts","in":"query","schema":{"type":"string","enum":["true"]}}],"responses":{"200":{"description":"Compliance alerts with statistics","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"alerts":{"type":"array","items":{"$ref":"#/components/schemas/ComplianceAlert"}},"stats":{"type":"object"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Compliance"],"operationId":"bulkAcknowledgeAlerts","summary":"Bulk acknowledge compliance alerts","description":"Acknowledges multiple pending compliance alerts at once. All specified alerts must exist and be in PENDING status.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkAcknowledgeRequest"}}}},"responses":{"200":{"description":"Alerts acknowledged","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"acknowledged":{"type":"integer"},"message":{"type":"string"}}}}}},"400":{"description":"Some alerts not found or already acknowledged","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/pki/sign":{"post":{"tags":["PKI"],"operationId":"createDigitalSignature","summary":"Create a digital signature","description":"Creates a 21 CFR Part 11 compliant digital signature using a signing certificate. Supports timestamping for non-repudiation.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignRequest"}}}},"responses":{"200":{"description":"Signature created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureResult"}}}},"400":{"description":"Missing required fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/pki/verify/{id}":{"get":{"tags":["PKI"],"operationId":"getSignatureDetails","summary":"Get signature details","description":"Retrieves signature details for a specific signature ID. Optionally retrieves all signatures for a resource when resourceType and resourceId query parameters are provided.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Signature ID"},{"name":"resourceType","in":"query","schema":{"type":"string"},"description":"Filter by resource type"},{"name":"resourceId","in":"query","schema":{"type":"string"},"description":"Filter by resource ID"}],"responses":{"200":{"description":"Signature details","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["PKI"],"operationId":"verifySignature","summary":"Verify a digital signature","description":"Verifies a digital signature against the provided document content. Checks document hash match, signature validity, certificate validity, and timestamp validity.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Signature ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyRequest"}}}},"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResult"}}}},"400":{"description":"Missing documentContent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/meetings":{"get":{"tags":["Meetings"],"operationId":"listMeetings","summary":"List IRB meetings","description":"Returns meetings for the authenticated user's organization. Supports filtering by status and upcoming meetings.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["SCHEDULED","IN_PROGRESS","COMPLETED","CANCELLED"]}},{"name":"upcoming","in":"query","schema":{"type":"string","enum":["true"]},"description":"Show only future meetings"}],"responses":{"200":{"description":"List of meetings","content":{"application/json":{"schema":{"type":"object","properties":{"meetings":{"type":"array","items":{"$ref":"#/components/schemas/Meeting"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Meetings"],"operationId":"createMeeting","summary":"Schedule a new IRB meeting","description":"Creates a new IRB meeting. Optionally links studies to the meeting agenda.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMeetingRequest"}}}},"responses":{"201":{"description":"Meeting created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Meeting"}}}},"400":{"description":"Missing required fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/budgets/{id}":{"get":{"tags":["Budgets"],"operationId":"getBudget","summary":"Get budget details","description":"Returns a budget with line items, site allocations, payments, and computed summary statistics including utilization percentages.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Budget ID"}],"responses":{"200":{"description":"Budget details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Budget"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Budget not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Budgets"],"operationId":"updateBudget","summary":"Update a budget","description":"Updates budget fields. When changing status to APPROVED, automatically records the approver and timestamp.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Budget ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBudgetRequest"}}}},"responses":{"200":{"description":"Updated budget","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Budget"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationError"}}}},"404":{"description":"Budget not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Budgets"],"operationId":"deleteBudget","summary":"Delete a budget","description":"Deletes a budget. Only budgets in DRAFT status can be deleted.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"cuid"},"description":"Budget ID"}],"responses":{"200":{"description":"Budget deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"400":{"description":"Only draft budgets can be deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Budget not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/notifications":{"get":{"tags":["Notifications"],"operationId":"listNotifications","summary":"Get user notifications","description":"Returns paginated notifications for the authenticated user. Supports filtering by unread status and category. Includes unread counts grouped by category.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"unreadOnly","in":"query","schema":{"type":"string","enum":["true"]}},{"name":"category","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Notifications with counts","content":{"application/json":{"schema":{"type":"object","properties":{"notifications":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"unreadCount":{"type":"integer"},"unreadByCategory":{"type":"object","additionalProperties":{"type":"integer"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Notifications"],"operationId":"createNotification","summary":"Create a notification","description":"Creates a notification for the authenticated user or another user (admin only). Primarily used by internal systems.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"userId":{"type":"string","description":"Target user (defaults to self)"},"type":{"type":"string"},"category":{"type":"string"},"title":{"type":"string"},"message":{"type":"string"},"link":{"type":"string"},"resourceType":{"type":"string"},"resourceId":{"type":"string"},"priority":{"type":"string","enum":["LOW","NORMAL","HIGH","URGENT"],"default":"NORMAL"},"metadata":{"type":"object"}}}}}},"responses":{"201":{"description":"Notification created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Notification"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden - admin required for other users","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/{...nextauth}":{"post":{"tags":["Auth"],"operationId":"nextAuth","summary":"NextAuth.js authentication","description":"Handles NextAuth.js authentication flows including sign-in, sign-out, session management, and OAuth callbacks. Supports credentials and Microsoft Entra ID providers.","parameters":[{"name":"...nextauth","in":"path","required":true,"schema":{"type":"string"},"description":"NextAuth route segment (e.g., signin, signout, session, callback)"}],"responses":{"200":{"description":"Authentication response varies by action"},"302":{"description":"Redirect to sign-in or callback URL"}}}},"/api/fhir-webhook/{resourceType}":{"post":{"tags":["FHIR"],"operationId":"handleFHIRWebhook","summary":"Receive FHIR webhook notification","description":"Receives FHIR subscription notifications when resources are created, updated, or deleted. Validates HMAC-SHA256 signatures, logs the event, and processes asynchronously. Supported resource types: research-study, research-subject, adverse-event, consent.","parameters":[{"name":"resourceType","in":"path","required":true,"schema":{"type":"string","enum":["research-study","research-subject","adverse-event","consent"]},"description":"FHIR resource type slug"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FHIRWebhookPayload"}}}},"responses":{"202":{"description":"Webhook accepted for async processing","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"accepted"},"requestId":{"type":"string","format":"uuid"},"resourceType":{"type":"string"},"resourceId":{"type":"string"},"eventType":{"type":"string","enum":["create","update","delete"]}}}}}},"400":{"description":"Unknown resource type or invalid payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Invalid webhook signature","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["FHIR"],"operationId":"getFHIRWebhookStatus","summary":"Get FHIR webhook endpoint status","description":"Returns the status of a FHIR webhook endpoint including recent events and 24-hour statistics.","parameters":[{"name":"resourceType","in":"path","required":true,"schema":{"type":"string","enum":["research-study","research-subject","adverse-event","consent"]}}],"responses":{"200":{"description":"Webhook endpoint status","content":{"application/json":{"schema":{"type":"object","properties":{"resourceType":{"type":"string"},"status":{"type":"string","example":"active"},"recentEvents":{"type":"array","items":{"type":"object"}},"last24Hours":{"type":"object"}}}}}},"404":{"description":"Unknown resource type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/video-consent/sessions":{"post":{"tags":["Video Consent"],"summary":"Create a video consent session","description":"Creates a new on-camera consent session. The session can be started immediately or scheduled for later.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["studyId","consentId","participantId"],"properties":{"studyId":{"type":"string","description":"Study ID"},"consentId":{"type":"string","description":"Consent document ID"},"participantId":{"type":"string","description":"Participant ID"},"witnessId":{"type":"string","description":"Optional witness user ID"},"scheduledAt":{"type":"string","format":"date-time","description":"Schedule for later (omit to start immediately)"},"notes":{"type":"string","description":"Session notes"}}}}}},"responses":{"201":{"description":"Session created successfully"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"404":{"description":"Study, consent, or participant not found"}}},"get":{"tags":["Video Consent"],"summary":"List video consent sessions","description":"Lists video consent sessions for a study with optional filtering. Available to all portals via API.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"studyId","in":"query","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["SCHEDULED","WAITING","IN_PROGRESS","CONSENT_REVIEW","SIGNING","COMPLETED","CANCELLED","FAILED"]}},{"name":"participantId","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}}],"responses":{"200":{"description":"Session list with pagination"},"400":{"description":"studyId is required"},"401":{"description":"Unauthorized"}}}},"/api/video-consent/sessions/{sessionId}":{"get":{"tags":["Video Consent"],"summary":"Get video consent session detail","description":"Returns full session details including audit trail. Accessible by all portals.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Session detail with audit entries"},"401":{"description":"Unauthorized"},"404":{"description":"Session not found"}}}},"/api/video-consent/sessions/{sessionId}/start":{"post":{"tags":["Video Consent"],"summary":"Start a video consent session","description":"Starts the session and transitions status to IN_PROGRESS. Only the assigned investigator can start.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Session started"},"400":{"description":"Session cannot be started from current status"},"401":{"description":"Unauthorized or not the assigned investigator"}}}},"/api/video-consent/sessions/{sessionId}/complete":{"post":{"tags":["Video Consent"],"summary":"Complete a video consent session","description":"Completes the session with recording upload, consent signature creation, PKI digital signature, and immutable audit log entry. Fires webhook events for external tool integration (eCOA, wearables, EDC, CTMS).","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["recording","signatureData","signedByName"],"properties":{"recording":{"type":"string","format":"binary","description":"Video recording file (WebM/MP4)"},"signatureMethod":{"type":"string","enum":["TYPED","DRAWN","VIDEO"]},"signatureData":{"type":"string","description":"Signature data (base64 or typed name)"},"signedByName":{"type":"string","description":"Full legal name of signer"},"recordingDurationMs":{"type":"integer","description":"Recording duration in milliseconds"},"witnessName":{"type":"string","description":"Witness name (if required)"},"witnessSignatureData":{"type":"string","description":"Witness signature data"},"signingFrameDataUrl":{"type":"string","description":"Base64 frame capture at signing moment"}}}}}},"responses":{"201":{"description":"Session completed, consent signed, recording uploaded"},"400":{"description":"Missing required data or witness signature"},"401":{"description":"Unauthorized"}}}},"/api/video-consent/sessions/{sessionId}/verify":{"post":{"tags":["Video Consent"],"summary":"Verify session integrity","description":"Re-verifies recording SHA-256 hash and PKI signature validity. Returns integrity status.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"type":"object","properties":{"recordingIntegrity":{"type":"object","properties":{"isValid":{"type":"boolean"},"expectedHash":{"type":"string"},"computedHash":{"type":"string"}}},"signatureValid":{"type":"boolean"},"overallValid":{"type":"boolean"}}}}}}}}},"/api/video-consent/sessions/{sessionId}/audit":{"get":{"tags":["Video Consent"],"summary":"Get session audit trail","description":"Returns the full audit trail for a video consent session. Accessible by all portals for compliance reporting.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Audit trail entries ordered by timestamp"},"401":{"description":"Unauthorized"}}},"post":{"tags":["Video Consent"],"summary":"Log an audit event","description":"Logs a video consent audit event with optional recording timestamp offset.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","description":"VideoConsentAuditAction enum value"},"details":{"type":"object","description":"Additional event details"},"recordingOffsetMs":{"type":"integer","description":"Milliseconds from recording start"}}}}}},"responses":{"201":{"description":"Audit entry created"}}}},"/api/video-consent/sessions/{sessionId}/recording":{"get":{"tags":["Video Consent"],"summary":"Get recording playback URL","description":"Returns a time-limited signed URL (SAS token) for video playback. URL expires after the specified duration.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}},{"name":"expiry","in":"query","schema":{"type":"integer","default":15,"description":"URL expiry in minutes"}}],"responses":{"200":{"description":"Signed URL for recording playback","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"expiresInMinutes":{"type":"integer"}}}}}},"404":{"description":"Recording not available"}}}},"/api/video-consent/zoom-token":{"post":{"tags":["Video Consent"],"summary":"Generate Zoom Video SDK JWT","description":"Generates a JWT token for Zoom Video SDK authentication. Used by all portals to join video consent sessions.","security":[{"BearerAuth":[]},{"SessionAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sessionName","role"],"properties":{"sessionName":{"type":"string"},"role":{"type":"string","enum":["host","participant"]}}}}}},"responses":{"200":{"description":"JWT token for Zoom Video SDK"},"503":{"description":"Zoom Video SDK not configured"}}}}}}