feat: move session sharing and collab rooms into a plugin (B12)

This commit is contained in:
LukeGus committed 2026-09-23 23:42:46 -05:00
1 parent 791d8656a1
commit a276f6898c
207 files changed
+35771 -11072

No files matched your search

-139
View File
@@ -761,70 +761,6 @@ export const sessionRecordings = mysqlTable(
],
);
export const sessionShares = mysqlTable(
"session_shares",
{
id: varchar("id", { length: 255 }).primaryKey(),
hostId: int("host_id")
.notNull()
.references(() => hosts.id, { onDelete: "cascade" }),
ownerUserId: varchar("owner_user_id", { length: 255 })
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
protocol: varchar("protocol", { length: 255 }).notNull(),
// Live-session binding: TerminalSessionManager's session.id for SSH, or
// guacd's own guacamoleConnectionId for rdp/vnc/telnet. Neither is a DB
// row (process-local, in-memory) so this intentionally has no FK.
sessionId: varchar("session_id", { length: 255 }).notNull(),
tabInstanceId: text("tab_instance_id"),
shareType: text("share_type").notNull(), // "link" | "user"
targetUserId: varchar("target_user_id", { length: 255 }).references(() => users.id, {
onDelete: "cascade",
}),
linkToken: varchar("link_token", { length: 255 }).unique(),
permissionLevel: text("permission_level").notNull().default("read-only"),
createdAt: varchar("created_at", { length: 255 })
.notNull()
.default(sql`(CURRENT_TIMESTAMP)`),
expiresAt: varchar("expires_at", { length: 255 }).notNull(),
revokedAt: text("revoked_at"),
lastJoinedAt: text("last_joined_at"),
joinCount: int("join_count").notNull().default(0),
},
// Resolved from the live session on join, and listed per host.
(table) => [
index("idx_session_shares_session_id").on(table.sessionId),
index("idx_session_shares_host_id").on(table.hostId),
],
);
export const sessionShareParticipants = mysqlTable(
"session_share_participants",
{
id: int("id").autoincrement().primaryKey(),
shareId: varchar("share_id", { length: 255 })
.notNull()
.references(() => sessionShares.id, { onDelete: "cascade" }),
userId: varchar("user_id", { length: 255 }).references(() => users.id, {
onDelete: "cascade",
}),
guestLabel: text("guest_label"),
joinedAt: text("joined_at")
.notNull()
.default(sql`(CURRENT_TIMESTAMP)`),
leftAt: text("left_at"),
},
);
export const opksshTokens = mysqlTable(
"opkssh_tokens",
{
@@ -1569,81 +1505,6 @@ export const aiProposals = mysqlTable(
// --- collab rooms ---
/**
* A collaboration room: a group of users watching one "stage" - the live
* session the current presenter is showing. The stage points at a
* shareType="room" row in session_shares, so transport, gating, recording and
* expiry all reuse the session-sharing machinery.
*/
export const collabRooms = mysqlTable(
"collab_rooms",
{
id: varchar("id", { length: 255 }).primaryKey(),
name: varchar("name", { length: 255 }).notNull(),
ownerUserId: varchar("owner_user_id", { length: 255 })
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
// Persistent rooms survive being emptied and can be re-used; one-off
// rooms are ended explicitly and never listed again.
persistent: boolean("persistent")
.notNull()
.default(false),
presenterUserId: varchar("presenter_user_id", { length: 255 }).references(() => users.id, {
onDelete: "set null",
}),
stageProtocol: text("stage_protocol"),
stageHostId: int("stage_host_id").references(() => hosts.id, {
onDelete: "set null",
}),
stageShareId: varchar("stage_share_id", { length: 255 }).references(() => sessionShares.id, {
onDelete: "set null",
}),
// Set = anonymous guests may watch the stage through this token.
guestLinkToken: varchar("guest_link_token", { length: 255 }),
createdAt: varchar("created_at", { length: 255 })
.notNull()
.default(sql`(CURRENT_TIMESTAMP)`),
endedAt: text("ended_at"),
},
(table) => [
index("idx_collab_rooms_owner").on(table.ownerUserId),
uniqueIndex("idx_collab_rooms_guest_token").on(table.guestLinkToken),
],
);
export const collabRoomMembers = mysqlTable(
"collab_room_members",
{
id: int("id").autoincrement().primaryKey(),
roomId: varchar("room_id", { length: 255 })
.notNull()
.references(() => collabRooms.id, { onDelete: "cascade" }),
userId: varchar("user_id", { length: 255 })
.notNull()
.references(() => users.id, { onDelete: "cascade" }),
// "host" runs the room: invites, force-switches the presenter, ends it.
roomRole: text("room_role").notNull().default("member"),
addedBy: varchar("added_by", { length: 255 }).references(() => users.id, {
onDelete: "set null",
}),
createdAt: varchar("created_at", { length: 255 })
.notNull()
.default(sql`(CURRENT_TIMESTAMP)`),
},
(table) => [
uniqueIndex("idx_collab_room_members_room_user").on(
table.roomId,
table.userId,
),
index("idx_collab_room_members_user").on(table.userId),
],
);
// --- secret sources ---
/**