UNPKG

@damourlabs/euro-clinical-trials

Version:

A Nuxt 3 application for visualizing and managing clinical trials data in Europe, built with modern web technologies.

70 lines (59 loc) 5.28 kB
import { z } from "zod"; import { AuditEntrySchema } from "./audits"; import { SiteSchema } from "./admin"; import { RegulatoryApprovalSchema, ComplianceStatusSchema, ProtocolDeviationSchema } from "./regulations" import { EndpointSchema, ParticipantEnrollmentSchema, RandomizationStrategySchema } from "./study"; import { BlindingEnum, TrialPhaseEnum, TrialStatusEnum } from "./enums"; // Administrative information subschema export const TrialAdministrativeSchema = z.object({ sponsorId: z.string().min(1, "Sponsor ID is required").default(() => crypto.randomUUID()).describe("Unique identifier for the sponsor of the trial"), principalInvestigatorId: z.string().min(1, "Principal Investigator ID is required").default(() => crypto.randomUUID()).describe("Unique identifier for the principal investigator of the trial"), sites: z.array(z.lazy(() => SiteSchema)).default([]).describe("List of clinical trial sites where the trial is being conducted"), }); export const TrialBasicInfoSchema = z.object({ eudraCTNumber: z.string().min(1, "EudraCT Number is required").default(() => crypto.randomUUID()).describe("Unique identifier for the trial in the EudraCT database"), description: z.string().min(1, "Trial description is required").default("No description provided").describe("Brief description of the clinical trial, including its objectives and scope"), id: z.string().uuid().optional().describe("Unique identifier for the trial"), indication: z.string().min(1, "Indication is required").default("General Indication").describe("Medical indication for which the trial is being conducted, e.g., 'Diabetes', 'Cancer', etc."), phase: TrialPhaseEnum.default(TrialPhaseEnum.Enum.I).describe("Phase of the trial, e.g., Phase I, II, III, or IV"), protocolNumber: z.string().min(1, "Protocol number is required").default(() => crypto.randomUUID()).describe("Unique identifier for the trial protocol"), title: z.string().min(1, "Trial title is required").default("Untitled Trial").describe("Title of the clinical trial, typically a short descriptive name"), }); // Regulatory and compliance subschema export const TrialRegulatoryComplianceSchema = z.object({ complianceStatus: z.lazy(() => ComplianceStatusSchema).describe("Overall compliance status of the trial, including GDPR and other regulations"), regulatoryApprovals: z.array(z.lazy(() => RegulatoryApprovalSchema)).default([]).describe("List of regulatory approvals for the trial"), protocolDeviations: z.array(z.lazy(() => ProtocolDeviationSchema)).default([]).describe("List of protocol deviations that have occurred during the trial"), auditTrail: z.array(z.lazy(() => AuditEntrySchema)).default([]).describe("Audit trail of actions taken during the trial, including changes to patient data, site information, and regulatory compliance"), }); // Study design subschema export const TrialStudyDesignSchema = z.object({ blinding: BlindingEnum.default(BlindingEnum.Enum.OpenLabel).describe("Type of blinding used in the trial, e.g., single, double, triple, or open label"), randomizationStrategy: z.lazy(() => RandomizationStrategySchema).describe("Randomization strategy used in the trial, including type, allocation ratio, block size, and stratification factors"), primaryEndpoint: z.lazy(() => EndpointSchema).describe("Primary endpoint of the trial, including its description, measurement method, target value, and unit of measurement"), secondaryEndpoints: z.array(z.lazy(() => EndpointSchema)).default([]).describe("List of secondary endpoints of the trial, each with its own description, measurement method, target value, and unit of measurement"), }); // Timeline and status subschema export const TrialTimelineSchema = z.object({ startDate: z.string().date().default(() => new Date().toISOString().split('T')[0]).describe("Start date of the trial, defaults to today if not provided"), estimatedEndDate: z.string().date().default(() => new Date(new Date().setFullYear(new Date().getFullYear() + 1)).toISOString().split('T')[0]).describe("Estimated end date of the trial, defaults to one year from today if not provided"), actualEndDate: z.string().date().optional().describe("Actual end date of the trial, if completed"), status: TrialStatusEnum.default(TrialStatusEnum.Enum.Planning), }); // Main Trial schema composed of subschemas export const TrialSchema = z.object({ id: z.string().uuid().describe("Unique identifier for the trial, automatically generated if not provided"), administrative: z.lazy(() => TrialAdministrativeSchema), basicInfo: z.lazy(() => TrialBasicInfoSchema), participantEnrollment: z.lazy(() => ParticipantEnrollmentSchema), regulatoryCompliance: z.lazy(() => TrialRegulatoryComplianceSchema), studyDesign: z.lazy(() => TrialStudyDesignSchema), timeline: z.lazy(() => TrialTimelineSchema), }); // Type inference export type Trial = z.infer<typeof TrialSchema> export type TrialBasicInfo = z.infer<typeof TrialBasicInfoSchema>; export type TrialTimeline = z.infer<typeof TrialTimelineSchema>; export type TrialRegulatoryCompliance = z.infer<typeof TrialRegulatoryComplianceSchema>; export type TrialStudyDesign = z.infer<typeof TrialStudyDesignSchema>; export type TrialAdministrative = z.infer<typeof TrialAdministrativeSchema>;