@studious-lms/server 1.2.51 → 1.2.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4547,7 +4547,7 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
4547
4547
  addMember: import("@trpc/server").TRPCMutationProcedure<{
4548
4548
  input: {
4549
4549
  conversationId: string;
4550
- memberId: string;
4550
+ memberUsername: string;
4551
4551
  };
4552
4552
  output: {
4553
4553
  type: import(".prisma/client").$Enums.ConversationType;
@@ -10107,7 +10107,7 @@ export declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
10107
10107
  addMember: import("@trpc/server").TRPCMutationProcedure<{
10108
10108
  input: {
10109
10109
  conversationId: string;
10110
- memberId: string;
10110
+ memberUsername: string;
10111
10111
  };
10112
10112
  output: {
10113
10113
  type: import(".prisma/client").$Enums.ConversationType;
@@ -139,7 +139,7 @@ export declare const conversationRouter: import("@trpc/server").TRPCBuiltRouter<
139
139
  addMember: import("@trpc/server").TRPCMutationProcedure<{
140
140
  input: {
141
141
  conversationId: string;
142
- memberId: string;
142
+ memberUsername: string;
143
143
  };
144
144
  output: {
145
145
  type: import(".prisma/client").$Enums.ConversationType;
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"/","sources":["routers/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwW7B,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"/","sources":["routers/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmX7B,CAAC"}
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1f7b92a6-0af0-5d8b-9470-dbfacbf4f6a3")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="191354b7-860c-5b1e-b227-64c88bc55b3e")}catch(e){}}();
3
3
  import { z } from 'zod';
4
4
  import { createTRPCRouter, protectedProcedure } from '../trpc.js';
5
5
  import { prisma } from '../lib/prisma.js';
@@ -289,10 +289,10 @@ export const conversationRouter = createTRPCRouter({
289
289
  return conversation;
290
290
  }),
291
291
  addMember: protectedProcedure
292
- .input(z.object({ conversationId: z.string(), memberId: z.string() }))
292
+ .input(z.object({ conversationId: z.string(), memberUsername: z.string() }))
293
293
  .mutation(async ({ input, ctx }) => {
294
294
  const userId = ctx.user.id;
295
- const { conversationId, memberId } = input;
295
+ const { conversationId, memberUsername } = input;
296
296
  const conversation = await prisma.conversation.findFirst({
297
297
  where: { id: conversationId, members: { some: { userId } } },
298
298
  });
@@ -302,8 +302,17 @@ export const conversationRouter = createTRPCRouter({
302
302
  message: 'Conversation not found or access denied',
303
303
  });
304
304
  }
305
+ const member = await prisma.user.findFirst({
306
+ where: { username: memberUsername },
307
+ });
308
+ if (!member) {
309
+ throw new TRPCError({
310
+ code: 'NOT_FOUND',
311
+ message: 'Member not found',
312
+ });
313
+ }
305
314
  await prisma.conversationMember.create({
306
- data: { userId: memberId, conversationId, role: 'MEMBER' },
315
+ data: { userId: member.id, conversationId, role: 'MEMBER' },
307
316
  });
308
317
  return conversation;
309
318
  }),
@@ -328,4 +337,4 @@ export const conversationRouter = createTRPCRouter({
328
337
  }),
329
338
  });
330
339
  //# sourceMappingURL=conversation.js.map
331
- //# debugId=1f7b92a6-0af0-5d8b-9470-dbfacbf4f6a3
340
+ //# debugId=191354b7-860c-5b1e-b227-64c88bc55b3e
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","sources":["routers/conversation.ts"],"sourceRoot":"/","sourcesContent":["import { z } from 'zod';\nimport { createTRPCRouter, protectedProcedure } from '../trpc.js';\nimport { prisma } from '../lib/prisma.js';\nimport { TRPCError } from '@trpc/server';\n\nexport const conversationRouter = createTRPCRouter({\n list: protectedProcedure.query(async ({ ctx }) => {\n const userId = ctx.user!.id;\n\n const conversations = await prisma.conversation.findMany({\n where: {\n members: {\n some: {\n userId,\n },\n },\n },\n include: {\n labChat: {\n select: {\n id: true,\n title: true,\n },\n },\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n messages: {\n orderBy: {\n createdAt: 'desc',\n },\n take: 1,\n include: {\n sender: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n },\n },\n },\n },\n },\n },\n },\n orderBy: {\n updatedAt: 'desc',\n },\n });\n\n // Calculate unread counts for each conversation\n const conversationsWithUnread = await Promise.all(\n conversations.map(async (conversation) => {\n const userMembership = conversation.members.find(m => m.userId === userId);\n const lastViewedAt = userMembership?.lastViewedAt;\n const lastViewedMentionAt = userMembership?.lastViewedMentionAt;\n \n // Count regular unread messages\n const unreadCount = await prisma.message.count({\n where: {\n conversationId: conversation.id,\n senderId: { not: userId },\n ...(lastViewedAt && {\n createdAt: { gt: lastViewedAt }\n }),\n },\n });\n\n // Count unread mentions\n // Use the later of lastViewedAt or lastViewedMentionAt\n // This means if user viewed conversation after mention, mention is considered read\n const mentionCutoffTime = lastViewedMentionAt && lastViewedAt \n ? (lastViewedMentionAt > lastViewedAt ? lastViewedMentionAt : lastViewedAt)\n : (lastViewedMentionAt || lastViewedAt);\n \n const unreadMentionCount = await prisma.mention.count({\n where: {\n userId,\n message: {\n conversationId: conversation.id,\n senderId: { not: userId },\n ...(mentionCutoffTime && {\n createdAt: { gt: mentionCutoffTime }\n }),\n },\n },\n });\n\n return {\n id: conversation.id,\n type: conversation.type,\n name: conversation.name,\n createdAt: conversation.createdAt,\n updatedAt: conversation.updatedAt,\n labChat: conversation.labChat,\n members: conversation.members,\n lastMessage: conversation.messages[0] || null,\n unreadCount,\n unreadMentionCount,\n };\n })\n );\n\n return conversationsWithUnread;\n }),\n\n create: protectedProcedure\n .input(\n z.object({\n type: z.enum(['DM', 'GROUP']),\n name: z.string().optional(),\n memberIds: z.array(z.string()),\n })\n )\n .mutation(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { type, name, memberIds } = input;\n\n // Validate input\n if (type === 'GROUP' && !name) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Group conversations must have a name',\n });\n }\n\n if (type === 'DM' && memberIds.length !== 1) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'DM conversations must have exactly one other member',\n });\n }\n\n // For DMs, check if conversation already exists\n if (type === 'DM') {\n // Get the target user's ID from their username\n const targetUser = await prisma.user.findFirst({\n where: { username: memberIds[0] },\n select: { id: true, username: true },\n });\n\n if (!targetUser) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `User \"${memberIds[0]}\" not found`,\n });\n }\n\n // Find all DM conversations where current user is a member\n const existingDMs = await prisma.conversation.findMany({\n where: {\n type: 'DM',\n members: {\n some: {\n userId,\n },\n },\n },\n include: {\n members: {\n select: {\n userId: true,\n },\n },\n },\n });\n\n // Check if any of these conversations has exactly 2 members (current user + target user)\n const existingDM = existingDMs.find(conv => {\n const memberUserIds = conv.members.map(m => m.userId);\n return memberUserIds.length === 2 &&\n memberUserIds.includes(userId) &&\n memberUserIds.includes(targetUser.id);\n });\n\n if (existingDM) {\n // Conversation already exists, throw error with friendly message\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `A conversation with ${targetUser.username} already exists`,\n });\n }\n }\n\n // Verify all members exist\n const membersWithIds = await prisma.user.findMany({\n where: {\n id: {\n in: memberIds,\n },\n },\n select: {\n id: true,\n username: true,\n },\n });\n\n const membersWithUsernames = await prisma.user.findMany({\n where: {\n username: {\n in: memberIds,\n },\n },\n select: {\n id: true,\n username: true,\n },\n });\n\n const members = [...membersWithIds, ...membersWithUsernames];\n\n if (members.length !== memberIds.length) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'One or more members not found',\n });\n }\n\n // Create conversation with members\n const conversation = await prisma.conversation.create({\n data: {\n type,\n name,\n members: {\n create: [\n {\n userId,\n role: type === 'GROUP' ? 'ADMIN' : 'MEMBER',\n },\n ...members.map((member) => ({\n userId: member.id,\n role: 'MEMBER' as const,\n })),\n ],\n },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n },\n });\n\n return conversation;\n }),\n\n get: protectedProcedure\n .input(z.object({ conversationId: z.string() }))\n .query(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { conversationId } = input;\n\n const conversation = await prisma.conversation.findFirst({\n where: {\n id: conversationId,\n members: {\n some: {\n userId,\n },\n },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n },\n });\n\n if (!conversation) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Conversation not found or access denied',\n });\n }\n\n return conversation;\n }),\n addMember: protectedProcedure\n .input(z.object({ conversationId: z.string(), memberId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { conversationId, memberId } = input;\n\n const conversation = await prisma.conversation.findFirst({\n where: { id: conversationId, members: { some: { userId } } },\n });\n\n if (!conversation) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Conversation not found or access denied',\n });\n }\n\n await prisma.conversationMember.create({\n data: { userId: memberId, conversationId, role: 'MEMBER' },\n });\n\n return conversation;\n }),\n\n removeMember: protectedProcedure\n .input(z.object({ conversationId: z.string(), memberId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { conversationId, memberId } = input;\n\n const conversation = await prisma.conversation.findFirst({\n where: { id: conversationId, members: { some: { userId } } },\n });\n\n if (!conversation) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Conversation not found or access denied',\n });\n }\n\n await prisma.conversationMember.delete({\n where: { userId_conversationId: { userId: memberId, conversationId } },\n });\n\n return conversation;\n }),\n});\n"],"names":[],"mappings":"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","debug_id":"1f7b92a6-0af0-5d8b-9470-dbfacbf4f6a3"}
1
+ {"version":3,"file":"conversation.js","sources":["routers/conversation.ts"],"sourceRoot":"/","sourcesContent":["import { z } from 'zod';\nimport { createTRPCRouter, protectedProcedure } from '../trpc.js';\nimport { prisma } from '../lib/prisma.js';\nimport { TRPCError } from '@trpc/server';\n\nexport const conversationRouter = createTRPCRouter({\n list: protectedProcedure.query(async ({ ctx }) => {\n const userId = ctx.user!.id;\n\n const conversations = await prisma.conversation.findMany({\n where: {\n members: {\n some: {\n userId,\n },\n },\n },\n include: {\n labChat: {\n select: {\n id: true,\n title: true,\n },\n },\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n messages: {\n orderBy: {\n createdAt: 'desc',\n },\n take: 1,\n include: {\n sender: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n },\n },\n },\n },\n },\n },\n },\n orderBy: {\n updatedAt: 'desc',\n },\n });\n\n // Calculate unread counts for each conversation\n const conversationsWithUnread = await Promise.all(\n conversations.map(async (conversation) => {\n const userMembership = conversation.members.find(m => m.userId === userId);\n const lastViewedAt = userMembership?.lastViewedAt;\n const lastViewedMentionAt = userMembership?.lastViewedMentionAt;\n \n // Count regular unread messages\n const unreadCount = await prisma.message.count({\n where: {\n conversationId: conversation.id,\n senderId: { not: userId },\n ...(lastViewedAt && {\n createdAt: { gt: lastViewedAt }\n }),\n },\n });\n\n // Count unread mentions\n // Use the later of lastViewedAt or lastViewedMentionAt\n // This means if user viewed conversation after mention, mention is considered read\n const mentionCutoffTime = lastViewedMentionAt && lastViewedAt \n ? (lastViewedMentionAt > lastViewedAt ? lastViewedMentionAt : lastViewedAt)\n : (lastViewedMentionAt || lastViewedAt);\n \n const unreadMentionCount = await prisma.mention.count({\n where: {\n userId,\n message: {\n conversationId: conversation.id,\n senderId: { not: userId },\n ...(mentionCutoffTime && {\n createdAt: { gt: mentionCutoffTime }\n }),\n },\n },\n });\n\n return {\n id: conversation.id,\n type: conversation.type,\n name: conversation.name,\n createdAt: conversation.createdAt,\n updatedAt: conversation.updatedAt,\n labChat: conversation.labChat,\n members: conversation.members,\n lastMessage: conversation.messages[0] || null,\n unreadCount,\n unreadMentionCount,\n };\n })\n );\n\n return conversationsWithUnread;\n }),\n\n create: protectedProcedure\n .input(\n z.object({\n type: z.enum(['DM', 'GROUP']),\n name: z.string().optional(),\n memberIds: z.array(z.string()),\n })\n )\n .mutation(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { type, name, memberIds } = input;\n\n // Validate input\n if (type === 'GROUP' && !name) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'Group conversations must have a name',\n });\n }\n\n if (type === 'DM' && memberIds.length !== 1) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'DM conversations must have exactly one other member',\n });\n }\n\n // For DMs, check if conversation already exists\n if (type === 'DM') {\n // Get the target user's ID from their username\n const targetUser = await prisma.user.findFirst({\n where: { username: memberIds[0] },\n select: { id: true, username: true },\n });\n\n if (!targetUser) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `User \"${memberIds[0]}\" not found`,\n });\n }\n\n // Find all DM conversations where current user is a member\n const existingDMs = await prisma.conversation.findMany({\n where: {\n type: 'DM',\n members: {\n some: {\n userId,\n },\n },\n },\n include: {\n members: {\n select: {\n userId: true,\n },\n },\n },\n });\n\n // Check if any of these conversations has exactly 2 members (current user + target user)\n const existingDM = existingDMs.find(conv => {\n const memberUserIds = conv.members.map(m => m.userId);\n return memberUserIds.length === 2 &&\n memberUserIds.includes(userId) &&\n memberUserIds.includes(targetUser.id);\n });\n\n if (existingDM) {\n // Conversation already exists, throw error with friendly message\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: `A conversation with ${targetUser.username} already exists`,\n });\n }\n }\n\n // Verify all members exist\n const membersWithIds = await prisma.user.findMany({\n where: {\n id: {\n in: memberIds,\n },\n },\n select: {\n id: true,\n username: true,\n },\n });\n\n const membersWithUsernames = await prisma.user.findMany({\n where: {\n username: {\n in: memberIds,\n },\n },\n select: {\n id: true,\n username: true,\n },\n });\n\n const members = [...membersWithIds, ...membersWithUsernames];\n\n if (members.length !== memberIds.length) {\n throw new TRPCError({\n code: 'BAD_REQUEST',\n message: 'One or more members not found',\n });\n }\n\n // Create conversation with members\n const conversation = await prisma.conversation.create({\n data: {\n type,\n name,\n members: {\n create: [\n {\n userId,\n role: type === 'GROUP' ? 'ADMIN' : 'MEMBER',\n },\n ...members.map((member) => ({\n userId: member.id,\n role: 'MEMBER' as const,\n })),\n ],\n },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n },\n });\n\n return conversation;\n }),\n\n get: protectedProcedure\n .input(z.object({ conversationId: z.string() }))\n .query(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { conversationId } = input;\n\n const conversation = await prisma.conversation.findFirst({\n where: {\n id: conversationId,\n members: {\n some: {\n userId,\n },\n },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n },\n });\n\n if (!conversation) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Conversation not found or access denied',\n });\n }\n\n return conversation;\n }),\n addMember: protectedProcedure\n .input(z.object({ conversationId: z.string(), memberUsername: z.string() }))\n .mutation(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { conversationId, memberUsername } = input;\n\n const conversation = await prisma.conversation.findFirst({\n where: { id: conversationId, members: { some: { userId } } },\n });\n\n if (!conversation) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Conversation not found or access denied',\n });\n }\n\n const member = await prisma.user.findFirst({\n where: { username: memberUsername },\n });\n\n if (!member) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Member not found',\n });\n }\n\n await prisma.conversationMember.create({\n data: { userId: member.id, conversationId, role: 'MEMBER' },\n });\n\n return conversation;\n }),\n\n removeMember: protectedProcedure\n .input(z.object({ conversationId: z.string(), memberId: z.string() }))\n .mutation(async ({ input, ctx }) => {\n const userId = ctx.user!.id;\n const { conversationId, memberId } = input;\n\n const conversation = await prisma.conversation.findFirst({\n where: { id: conversationId, members: { some: { userId } } },\n });\n\n if (!conversation) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Conversation not found or access denied',\n });\n }\n\n await prisma.conversationMember.delete({\n where: { userId_conversationId: { userId: memberId, conversationId } },\n });\n\n return conversation;\n }),\n});\n"],"names":[],"mappings":"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","debug_id":"191354b7-860c-5b1e-b227-64c88bc55b3e"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studious-lms/server",
3
- "version": "1.2.51",
3
+ "version": "1.2.52",
4
4
  "description": "Backend server for Studious application",
5
5
  "main": "dist/exportType.js",
6
6
  "types": "dist/exportType.d.ts",
@@ -317,10 +317,10 @@ export const conversationRouter = createTRPCRouter({
317
317
  return conversation;
318
318
  }),
319
319
  addMember: protectedProcedure
320
- .input(z.object({ conversationId: z.string(), memberId: z.string() }))
320
+ .input(z.object({ conversationId: z.string(), memberUsername: z.string() }))
321
321
  .mutation(async ({ input, ctx }) => {
322
322
  const userId = ctx.user!.id;
323
- const { conversationId, memberId } = input;
323
+ const { conversationId, memberUsername } = input;
324
324
 
325
325
  const conversation = await prisma.conversation.findFirst({
326
326
  where: { id: conversationId, members: { some: { userId } } },
@@ -333,8 +333,19 @@ export const conversationRouter = createTRPCRouter({
333
333
  });
334
334
  }
335
335
 
336
+ const member = await prisma.user.findFirst({
337
+ where: { username: memberUsername },
338
+ });
339
+
340
+ if (!member) {
341
+ throw new TRPCError({
342
+ code: 'NOT_FOUND',
343
+ message: 'Member not found',
344
+ });
345
+ }
346
+
336
347
  await prisma.conversationMember.create({
337
- data: { userId: memberId, conversationId, role: 'MEMBER' },
348
+ data: { userId: member.id, conversationId, role: 'MEMBER' },
338
349
  });
339
350
 
340
351
  return conversation;