mirror of
https://github.com/temetro/temetro.git
synced 2026-08-13 03:56:53 +00:00
913a217e1d
- Live invite: ring a clinic member into a room (socket call:invite + a bell notification); the invitee gets a toast with a Join action. Notifications of type "meeting" deep-link to /messages/meetings?room=, which auto-joins. - Scheduling: new scheduled_meetings table + /api/meetings/events (list mine, create, delete); a Calendar tab on the Meetings page with a month picker (meeting-day dots), the day's agenda, and a Schedule-meeting dialog (title/date/time/participants). - Redesign: rounded control bar with tooltips (mic/cam/screen/invite + separated red Leave), speaking ring on tiles (Web Audio), and live room-occupancy counts via call:presence broadcasts. Migration 0025. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import {
|
|
index,
|
|
jsonb,
|
|
pgTable,
|
|
text,
|
|
timestamp,
|
|
uuid,
|
|
} from "drizzle-orm/pg-core";
|
|
|
|
import { organization, user } from "./auth.js";
|
|
|
|
// A persistent staff meeting room (Discord-style voice/video channel), scoped to
|
|
// a clinic. Rooms are long-lived "channels"; the live call (participants, media)
|
|
// is ephemeral and lives only in the realtime layer — nothing about an in-call
|
|
// session is persisted here.
|
|
export const meetingRooms = pgTable(
|
|
"meeting_rooms",
|
|
{
|
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
organizationId: text("organization_id")
|
|
.notNull()
|
|
.references(() => organization.id, { onDelete: "cascade" }),
|
|
name: text("name").notNull(),
|
|
createdBy: text("created_by").references(() => user.id, {
|
|
onDelete: "set null",
|
|
}),
|
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
},
|
|
(table) => [index("meeting_rooms_org_idx").on(table.organizationId)],
|
|
);
|
|
|
|
// A scheduled staff meeting (calendar event), scoped to a clinic. `participants`
|
|
// holds the invited staff user ids; `date`/`time` are local strings (YYYY-MM-DD /
|
|
// HH:mm) like appointments, to avoid timezone drift on the calendar.
|
|
export const scheduledMeetings = pgTable(
|
|
"scheduled_meetings",
|
|
{
|
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
organizationId: text("organization_id")
|
|
.notNull()
|
|
.references(() => organization.id, { onDelete: "cascade" }),
|
|
title: text("title").notNull(),
|
|
date: text("date").notNull(),
|
|
time: text("time").notNull(),
|
|
participants: jsonb("participants").$type<string[]>().notNull().default([]),
|
|
createdBy: text("created_by").references(() => user.id, {
|
|
onDelete: "set null",
|
|
}),
|
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
},
|
|
(table) => [index("scheduled_meetings_org_idx").on(table.organizationId)],
|
|
);
|