feat: implement WebSocket for real-time trial updates

- Create standalone WebSocket server (ws-server.ts) on port 3001 using Bun
- Add ws_connections table to track active connections in database
- Create global WebSocket manager that persists across component unmounts
- Fix useWebSocket hook to prevent infinite re-renders and use refs
- Fix TrialForm Select components with proper default values
- Add trialId to WebSocket URL for server-side tracking
- Update package.json with dev:ws script for separate WS server
This commit is contained in:
2026-03-22 00:48:43 -04:00
parent 20d6d3de1a
commit a5762ec935
9 changed files with 1257 additions and 481 deletions
+7 -2
View File
@@ -163,6 +163,11 @@ export function TrialForm({ mode, trialId, studyId }: TrialFormProps) {
const form = useForm<TrialFormData>({
resolver: zodResolver(trialSchema),
defaultValues: {
experimentId: "" as any,
participantId: "" as any,
scheduledAt: new Date(),
wizardId: undefined,
notes: "",
sessionNumber: 1,
},
});
@@ -347,7 +352,7 @@ export function TrialForm({ mode, trialId, studyId }: TrialFormProps) {
<FormField>
<Label htmlFor="experimentId">Experiment *</Label>
<Select
value={form.watch("experimentId")}
value={form.watch("experimentId") ?? ""}
onValueChange={(value) => form.setValue("experimentId", value)}
disabled={experimentsLoading || mode === "edit"}
>
@@ -387,7 +392,7 @@ export function TrialForm({ mode, trialId, studyId }: TrialFormProps) {
<FormField>
<Label htmlFor="participantId">Participant *</Label>
<Select
value={form.watch("participantId")}
value={form.watch("participantId") ?? ""}
onValueChange={(value) => form.setValue("participantId", value)}
disabled={participantsLoading || mode === "edit"}
>