feat(messages): attach files and share appointments

- new message_attachments table + POST/GET /api/conversations/attachments
  (base64 upload, capped 10MB; authed clinic-scoped download)
- messages carry an attachments JSON column (file refs or appointment
  snapshots); realtime + REST send accept attachments and allow
  attachment-only messages; migration 0019
- composer "+" menu (Files / Appointments): file picker uploads and
  stages chips; appointment picker searches by patient and attaches a
  snapshot; both render in the thread (download chip / appointment card)
- raise express json limit to 15mb for base64 uploads

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-15 18:58:11 +03:00
parent addddc8972
commit 15fc7fdf26
12 changed files with 3971 additions and 44 deletions
+16
View File
@@ -0,0 +1,16 @@
CREATE TABLE "message_attachments" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"organization_id" text NOT NULL,
"uploader_id" text,
"file_name" text NOT NULL,
"mime_type" text NOT NULL,
"size" integer NOT NULL,
"data" text NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "messages" ALTER COLUMN "body" SET DEFAULT '';--> statement-breakpoint
ALTER TABLE "messages" ADD COLUMN "attachments" jsonb;--> statement-breakpoint
ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "message_attachments" ADD CONSTRAINT "message_attachments_uploader_id_user_id_fk" FOREIGN KEY ("uploader_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "message_attachments_org_idx" ON "message_attachments" USING btree ("organization_id");
File diff suppressed because it is too large Load Diff
+7
View File
@@ -134,6 +134,13 @@
"when": 1781537902724,
"tag": "0018_clean_doctor_strange",
"breakpoints": true
},
{
"idx": 19,
"version": "7",
"when": 1781538797034,
"tag": "0019_black_mole_man",
"breakpoints": true
}
]
}