@studious-lms/server 1.4.3 → 1.4.5
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.
- package/.vscode/settings.json +3 -0
- package/dist/index.js +4 -18
- package/dist/index.js.map +1 -1
- package/dist/models/conversation.d.ts +22 -0
- package/dist/models/conversation.d.ts.map +1 -1
- package/dist/models/conversation.js +13 -2
- package/dist/models/conversation.js.map +1 -1
- package/dist/models/labChat.d.ts +3 -0
- package/dist/models/labChat.d.ts.map +1 -1
- package/dist/models/message.d.ts +2 -0
- package/dist/models/message.d.ts.map +1 -1
- package/dist/models/newtonChat.d.ts +1 -0
- package/dist/models/newtonChat.d.ts.map +1 -1
- package/dist/models/worksheet.d.ts +1 -0
- package/dist/models/worksheet.d.ts.map +1 -1
- package/dist/models/worksheet.js +2 -2
- package/dist/models/worksheet.js.map +1 -1
- package/dist/pipelines/pdfToWorksheet.d.ts +12 -0
- package/dist/pipelines/pdfToWorksheet.d.ts.map +1 -0
- package/dist/pipelines/pdfToWorksheet.js +155 -0
- package/dist/pipelines/pdfToWorksheet.js.map +1 -0
- package/dist/routers/_app.d.ts +252 -0
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +4 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/conversation.d.ts +14 -0
- package/dist/routers/conversation.d.ts.map +1 -1
- package/dist/routers/conversation.js +6 -3
- package/dist/routers/conversation.js.map +1 -1
- package/dist/routers/labChat.d.ts +2 -0
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/search.d.ts +41 -0
- package/dist/routers/search.d.ts.map +1 -0
- package/dist/routers/search.js +15 -0
- package/dist/routers/search.js.map +1 -0
- package/dist/routers/worksheet.d.ts +71 -0
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +110 -3
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/services/conversation.d.ts +8 -0
- package/dist/services/conversation.d.ts.map +1 -1
- package/dist/services/conversation.js +24 -6
- package/dist/services/conversation.js.map +1 -1
- package/dist/services/labChat.d.ts +2 -0
- package/dist/services/labChat.d.ts.map +1 -1
- package/dist/services/message.d.ts.map +1 -1
- package/dist/services/message.js +9 -2
- package/dist/services/message.js.map +1 -1
- package/dist/services/search.d.ts +21 -0
- package/dist/services/search.d.ts.map +1 -0
- package/dist/services/search.js +352 -0
- package/dist/services/search.js.map +1 -0
- package/dist/services/worksheet.d.ts +21 -0
- package/dist/services/worksheet.d.ts.map +1 -1
- package/dist/services/worksheet.js +50 -2
- package/dist/services/worksheet.js.map +1 -1
- package/dist/utils/inference.d.ts +2 -1
- package/dist/utils/inference.d.ts.map +1 -1
- package/dist/utils/inference.js +53 -5
- package/dist/utils/inference.js.map +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20260417083000_add_conversation_member_hidden_at/migration.sql +2 -0
- package/prisma/schema.prisma +1 -0
- package/src/index.ts +4 -19
- package/src/models/conversation.ts +12 -0
- package/src/models/worksheet.ts +1 -0
- package/src/pipelines/pdfToWorksheet.ts +177 -0
- package/src/routers/_app.ts +2 -0
- package/src/routers/conversation.ts +7 -0
- package/src/routers/search.ts +14 -0
- package/src/routers/worksheet.ts +143 -0
- package/src/services/conversation.ts +27 -3
- package/src/services/message.ts +8 -0
- package/src/services/search.ts +397 -0
- package/src/services/worksheet.ts +61 -0
- package/src/utils/inference.ts +77 -7
- package/tests/pipelines/pdfToWorksheet.test.ts +176 -0
- package/tests/routers/conversation.test.ts +114 -2
- package/tests/routers/search.test.ts +109 -0
- package/tests/utils/inference.test.ts +37 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const searchRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
3
|
+
ctx: import("../trpc.js").Context;
|
|
4
|
+
meta: object;
|
|
5
|
+
errorShape: {
|
|
6
|
+
data: {
|
|
7
|
+
zodError: z.typeToFlattenedError<any, string> | null;
|
|
8
|
+
prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
|
|
9
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
10
|
+
httpStatus: number;
|
|
11
|
+
path?: string;
|
|
12
|
+
stack?: string;
|
|
13
|
+
};
|
|
14
|
+
message: string;
|
|
15
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
16
|
+
};
|
|
17
|
+
transformer: false;
|
|
18
|
+
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
19
|
+
global: import("@trpc/server").TRPCQueryProcedure<{
|
|
20
|
+
input: {
|
|
21
|
+
query?: string | undefined;
|
|
22
|
+
limit?: number | undefined;
|
|
23
|
+
};
|
|
24
|
+
output: {
|
|
25
|
+
query: string;
|
|
26
|
+
results: {
|
|
27
|
+
id: string;
|
|
28
|
+
type: "file" | "class" | "section" | "syllabus" | "assignment" | "event" | "announcement" | "worksheet";
|
|
29
|
+
title: string;
|
|
30
|
+
subtitle: string;
|
|
31
|
+
classId: string;
|
|
32
|
+
className: string;
|
|
33
|
+
href: string;
|
|
34
|
+
matchedText?: string | null;
|
|
35
|
+
date?: Date | null;
|
|
36
|
+
}[];
|
|
37
|
+
};
|
|
38
|
+
meta: object;
|
|
39
|
+
}>;
|
|
40
|
+
}>>;
|
|
41
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"/","sources":["routers/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GASvB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
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]="5056f983-6413-5428-8066-7a3a63836b94")}catch(e){}}();
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
|
|
5
|
+
import { searchGlobalClasses } from "../services/search.js";
|
|
6
|
+
export const searchRouter = createTRPCRouter({
|
|
7
|
+
global: protectedProcedure
|
|
8
|
+
.input(z.object({
|
|
9
|
+
query: z.string().max(80).optional(),
|
|
10
|
+
limit: z.number().int().min(1).max(30).optional(),
|
|
11
|
+
}))
|
|
12
|
+
.query(({ ctx, input }) => searchGlobalClasses(ctx.user.id, input)),
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=search.js.map
|
|
15
|
+
//# debugId=5056f983-6413-5428-8066-7a3a63836b94
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sources":["routers/search.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport { createTRPCRouter, protectedProcedure } from \"../trpc.js\";\nimport { searchGlobalClasses } from \"../services/search.js\";\n\nexport const searchRouter = createTRPCRouter({\n global: protectedProcedure\n .input(\n z.object({\n query: z.string().max(80).optional(),\n limit: z.number().int().min(1).max(30).optional(),\n })\n )\n .query(({ ctx, input }) => searchGlobalClasses(ctx.user!.id, input)),\n});\n"],"names":[],"mappings":";;AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;IAC3C,MAAM,EAAE,kBAAkB;SACvB,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;QACpC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;KAClD,CAAC,CACH;SACA,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;CACvE,CAAC,CAAC","debug_id":"5056f983-6413-5428-8066-7a3a63836b94"}
|
|
@@ -121,6 +121,66 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
121
121
|
};
|
|
122
122
|
meta: object;
|
|
123
123
|
}>;
|
|
124
|
+
createFromPdf: import("@trpc/server").TRPCMutationProcedure<{
|
|
125
|
+
input: {
|
|
126
|
+
[x: string]: unknown;
|
|
127
|
+
classId: string;
|
|
128
|
+
url: string;
|
|
129
|
+
};
|
|
130
|
+
output: {
|
|
131
|
+
name: string;
|
|
132
|
+
id: string;
|
|
133
|
+
createdAt: Date;
|
|
134
|
+
classId: string;
|
|
135
|
+
updatedAt: Date;
|
|
136
|
+
};
|
|
137
|
+
meta: object;
|
|
138
|
+
}>;
|
|
139
|
+
getWorksheetUploadUrls: import("@trpc/server").TRPCMutationProcedure<{
|
|
140
|
+
input: {
|
|
141
|
+
[x: string]: unknown;
|
|
142
|
+
classId: string;
|
|
143
|
+
files: {
|
|
144
|
+
type: string;
|
|
145
|
+
name: string;
|
|
146
|
+
size: number;
|
|
147
|
+
}[];
|
|
148
|
+
};
|
|
149
|
+
output: {
|
|
150
|
+
success: boolean;
|
|
151
|
+
uploadFiles: import("../lib/fileUpload.js").DirectUploadFile[];
|
|
152
|
+
};
|
|
153
|
+
meta: object;
|
|
154
|
+
}>;
|
|
155
|
+
confirmWorksheetUpload: import("@trpc/server").TRPCMutationProcedure<{
|
|
156
|
+
input: {
|
|
157
|
+
[x: string]: unknown;
|
|
158
|
+
classId: string;
|
|
159
|
+
fileId: string;
|
|
160
|
+
uploadSuccess: boolean;
|
|
161
|
+
errorMessage?: string | undefined;
|
|
162
|
+
};
|
|
163
|
+
output: {
|
|
164
|
+
success: boolean;
|
|
165
|
+
message: string;
|
|
166
|
+
};
|
|
167
|
+
meta: object;
|
|
168
|
+
}>;
|
|
169
|
+
createFromUploadedPdf: import("@trpc/server").TRPCMutationProcedure<{
|
|
170
|
+
input: {
|
|
171
|
+
[x: string]: unknown;
|
|
172
|
+
classId: string;
|
|
173
|
+
fileId: string;
|
|
174
|
+
};
|
|
175
|
+
output: {
|
|
176
|
+
name: string;
|
|
177
|
+
id: string;
|
|
178
|
+
createdAt: Date;
|
|
179
|
+
classId: string;
|
|
180
|
+
updatedAt: Date;
|
|
181
|
+
};
|
|
182
|
+
meta: object;
|
|
183
|
+
}>;
|
|
124
184
|
addQuestion: import("@trpc/server").TRPCMutationProcedure<{
|
|
125
185
|
input: {
|
|
126
186
|
type: "ESSAY" | "MULTIPLE_CHOICE" | "TRUE_FALSE" | "SHORT_ANSWER" | "LONG_ANSWER" | "MATH_EXPRESSION";
|
|
@@ -360,5 +420,16 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
360
420
|
};
|
|
361
421
|
meta: object;
|
|
362
422
|
}>;
|
|
423
|
+
updateUploadProgress: import("@trpc/server").TRPCMutationProcedure<{
|
|
424
|
+
input: {
|
|
425
|
+
fileId: string;
|
|
426
|
+
progress: number;
|
|
427
|
+
};
|
|
428
|
+
output: {
|
|
429
|
+
success: boolean;
|
|
430
|
+
progress: number;
|
|
431
|
+
};
|
|
432
|
+
meta: object;
|
|
433
|
+
}>;
|
|
363
434
|
}>>;
|
|
364
435
|
//# sourceMappingURL=worksheet.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["routers/worksheet.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["routers/worksheet.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwDxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiV1B,CAAC"}
|
|
@@ -1,9 +1,39 @@
|
|
|
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]="
|
|
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]="31932b12-1093-5e0f-a21c-e9301dcb8c25")}catch(e){}}();
|
|
3
3
|
import { TRPCError } from "@trpc/server";
|
|
4
|
+
import { prisma } from "../lib/prisma.js";
|
|
5
|
+
import { confirmDirectUpload, createDirectUploadFiles, updateUploadProgress, } from "../lib/fileUpload.js";
|
|
4
6
|
import { createTRPCRouter, protectedClassMemberProcedure, protectedProcedure, protectedTeacherProcedure, } from "../trpc.js";
|
|
5
7
|
import { z } from "zod";
|
|
6
|
-
import { getWorksheet, worksheetExists, listWorksheets, updateWorksheetRecord, deleteWorksheetRecord, createWorksheetRecord, addQuestionToWorksheet, reorderWorksheetQuestions, updateWorksheetQuestionRecord, deleteWorksheetQuestionRecord, getWorksheetSubmission, answerWorksheetQuestion, cancelGrading, regradeQuestion, gradeAnswer, addCommentToResponse, } from "../services/worksheet.js";
|
|
8
|
+
import { getWorksheet, worksheetExists, listWorksheets, updateWorksheetRecord, deleteWorksheetRecord, createWorksheetRecord, createWorksheetFromPdf, createWorksheetFromUploadedPdf, addQuestionToWorksheet, reorderWorksheetQuestions, updateWorksheetQuestionRecord, deleteWorksheetQuestionRecord, getWorksheetSubmission, answerWorksheetQuestion, cancelGrading, regradeQuestion, gradeAnswer, addCommentToResponse, } from "../services/worksheet.js";
|
|
9
|
+
const directFileSchema = z.object({
|
|
10
|
+
name: z.string(),
|
|
11
|
+
type: z.string(),
|
|
12
|
+
size: z.number(),
|
|
13
|
+
});
|
|
14
|
+
const pdfFileSchema = directFileSchema.superRefine((file, ctx) => {
|
|
15
|
+
const isPdf = file.type === "application/pdf" && file.name.toLowerCase().endsWith(".pdf");
|
|
16
|
+
if (!isPdf) {
|
|
17
|
+
ctx.addIssue({
|
|
18
|
+
code: z.ZodIssueCode.custom,
|
|
19
|
+
message: "Only PDF files are supported",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
const getWorksheetUploadUrlsSchema = z.object({
|
|
24
|
+
classId: z.string(),
|
|
25
|
+
files: z.array(pdfFileSchema),
|
|
26
|
+
});
|
|
27
|
+
const confirmWorksheetUploadSchema = z.object({
|
|
28
|
+
classId: z.string(),
|
|
29
|
+
fileId: z.string(),
|
|
30
|
+
uploadSuccess: z.boolean(),
|
|
31
|
+
errorMessage: z.string().optional(),
|
|
32
|
+
});
|
|
33
|
+
const updateUploadProgressSchema = z.object({
|
|
34
|
+
fileId: z.string(),
|
|
35
|
+
progress: z.number().min(0).max(100),
|
|
36
|
+
});
|
|
7
37
|
export const worksheetRouter = createTRPCRouter({
|
|
8
38
|
getWorksheet: protectedProcedure
|
|
9
39
|
.input(z.object({ worksheetId: z.string() }))
|
|
@@ -33,6 +63,56 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
33
63
|
create: protectedTeacherProcedure
|
|
34
64
|
.input(z.object({ classId: z.string(), name: z.string() }))
|
|
35
65
|
.mutation(({ input }) => createWorksheetRecord(input.classId, input.name)),
|
|
66
|
+
createFromPdf: protectedTeacherProcedure
|
|
67
|
+
.input(z.object({ classId: z.string(), url: z.string().url() }))
|
|
68
|
+
.mutation(({ input }) => createWorksheetFromPdf(input.classId, input.url)),
|
|
69
|
+
getWorksheetUploadUrls: protectedTeacherProcedure
|
|
70
|
+
.input(getWorksheetUploadUrlsSchema)
|
|
71
|
+
.mutation(async ({ ctx, input }) => {
|
|
72
|
+
if (!ctx.user) {
|
|
73
|
+
throw new TRPCError({
|
|
74
|
+
code: "UNAUTHORIZED",
|
|
75
|
+
message: "You must be logged in to upload files",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const uploadFiles = await createDirectUploadFiles(input.files, ctx.user.id);
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
uploadFiles,
|
|
82
|
+
};
|
|
83
|
+
}),
|
|
84
|
+
confirmWorksheetUpload: protectedTeacherProcedure
|
|
85
|
+
.input(confirmWorksheetUploadSchema)
|
|
86
|
+
.mutation(async ({ ctx, input }) => {
|
|
87
|
+
if (!ctx.user) {
|
|
88
|
+
throw new TRPCError({
|
|
89
|
+
code: "UNAUTHORIZED",
|
|
90
|
+
message: "You must be logged in",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
const file = await prisma.file.findFirst({
|
|
94
|
+
where: {
|
|
95
|
+
id: input.fileId,
|
|
96
|
+
userId: ctx.user.id,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
if (!file) {
|
|
100
|
+
throw new TRPCError({
|
|
101
|
+
code: "NOT_FOUND",
|
|
102
|
+
message: "File not found or you don't have permission",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
await confirmDirectUpload(input.fileId, input.uploadSuccess, input.errorMessage);
|
|
106
|
+
return {
|
|
107
|
+
success: true,
|
|
108
|
+
message: input.uploadSuccess
|
|
109
|
+
? "Upload confirmed successfully"
|
|
110
|
+
: "Upload failed",
|
|
111
|
+
};
|
|
112
|
+
}),
|
|
113
|
+
createFromUploadedPdf: protectedTeacherProcedure
|
|
114
|
+
.input(z.object({ classId: z.string(), fileId: z.string() }))
|
|
115
|
+
.mutation(({ ctx, input }) => createWorksheetFromUploadedPdf(input.classId, input.fileId, ctx.user.id)),
|
|
36
116
|
addQuestion: protectedProcedure
|
|
37
117
|
.input(z.object({
|
|
38
118
|
worksheetId: z.string(),
|
|
@@ -150,6 +230,33 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
150
230
|
comment: z.string(),
|
|
151
231
|
}))
|
|
152
232
|
.mutation(({ ctx, input }) => addCommentToResponse(input.responseId, input.comment, ctx.user.id)),
|
|
233
|
+
updateUploadProgress: protectedProcedure
|
|
234
|
+
.input(updateUploadProgressSchema)
|
|
235
|
+
.mutation(async ({ ctx, input }) => {
|
|
236
|
+
if (!ctx.user) {
|
|
237
|
+
throw new TRPCError({
|
|
238
|
+
code: "UNAUTHORIZED",
|
|
239
|
+
message: "You must be logged in",
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
const file = await prisma.file.findFirst({
|
|
243
|
+
where: {
|
|
244
|
+
id: input.fileId,
|
|
245
|
+
userId: ctx.user.id,
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
if (!file) {
|
|
249
|
+
throw new TRPCError({
|
|
250
|
+
code: "NOT_FOUND",
|
|
251
|
+
message: "File not found or you don't have permission",
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
await updateUploadProgress(input.fileId, input.progress);
|
|
255
|
+
return {
|
|
256
|
+
success: true,
|
|
257
|
+
progress: input.progress,
|
|
258
|
+
};
|
|
259
|
+
}),
|
|
153
260
|
});
|
|
154
261
|
//# sourceMappingURL=worksheet.js.map
|
|
155
|
-
//# debugId=
|
|
262
|
+
//# debugId=31932b12-1093-5e0f-a21c-e9301dcb8c25
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport {\n createTRPCRouter,\n protectedClassMemberProcedure,\n protectedProcedure,\n protectedTeacherProcedure,\n} from \"../trpc.js\";\nimport { z } from \"zod\";\nimport {\n getWorksheet,\n worksheetExists,\n listWorksheets,\n updateWorksheetRecord,\n deleteWorksheetRecord,\n createWorksheetRecord,\n addQuestionToWorksheet,\n reorderWorksheetQuestions,\n updateWorksheetQuestionRecord,\n deleteWorksheetQuestionRecord,\n getWorksheetSubmission,\n answerWorksheetQuestion,\n cancelGrading,\n regradeQuestion,\n gradeAnswer,\n addCommentToResponse,\n} from \"../services/worksheet.js\";\n\nexport const worksheetRouter = createTRPCRouter({\n getWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .query(({ ctx, input }) => getWorksheet(input.worksheetId, ctx.user!.id)),\n\n exists: protectedClassMemberProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n return worksheetExists(input.id);\n }),\n\n listWorksheets: protectedClassMemberProcedure\n .input(z.object({ classId: z.string() }))\n .query(({ input }) => listWorksheets(input.classId)),\n\n updateWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string(), name: z.string().optional() }))\n .mutation(({ ctx, input }) =>\n updateWorksheetRecord(input.worksheetId, ctx.user!.id, {\n name: input.name,\n })\n ),\n\n deleteWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .mutation(({ ctx, input }) =>\n deleteWorksheetRecord(input.worksheetId, ctx.user!.id)\n ),\n\n create: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), name: z.string() }))\n .mutation(({ input }) =>\n createWorksheetRecord(input.classId, input.name)\n ),\n\n addQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z.enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ]),\n })\n )\n .mutation(({ ctx, input }) =>\n addQuestionToWorksheet(input.worksheetId, ctx.user!.id, {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n })\n ),\n\n reorderQuestions: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum([\"before\", \"after\"]),\n targetId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n reorderWorksheetQuestions(\n input.worksheetId,\n ctx.user!.id,\n input.movedId,\n input.position,\n input.targetId\n )\n ),\n\n updateQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z\n .enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ])\n .optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n updateWorksheetQuestionRecord(\n input.worksheetId,\n input.questionId,\n ctx.user!.id,\n {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n }\n )\n ),\n\n deleteQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n deleteWorksheetQuestionRecord(\n input.worksheetId,\n input.questionId,\n ctx.user!.id\n )\n ),\n\n getWorksheetSubmission: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n })\n )\n .query(({ ctx, input }) =>\n getWorksheetSubmission(input.worksheetId, input.submissionId, ctx.user!.id)\n ),\n\n answerQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n answerWorksheetQuestion(\n input.worksheetResponseId,\n input.questionId,\n input.response,\n ctx.user!.id\n )\n ),\n\n cancelGrading: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n cancelGrading(input.worksheetResponseId, input.progressId, ctx.user!.id)\n ),\n\n regradeQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n regradeQuestion(input.worksheetResponseId, input.progressId, ctx.user!.id)\n ),\n\n gradeAnswer: protectedProcedure\n .input(\n z.object({\n questionId: z.string(),\n responseId: z.string().optional(),\n studentWorksheetResponseId: z.string(),\n response: z.string().optional(),\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n gradeAnswer(\n input.questionId,\n input.studentWorksheetResponseId,\n ctx.user!.id,\n {\n responseId: input.responseId,\n response: input.response,\n isCorrect: input.isCorrect,\n feedback: input.feedback,\n markschemeState: input.markschemeState,\n points: input.points,\n }\n )\n ),\n\n addComment: protectedProcedure\n .input(\n z.object({\n responseId: z.string(),\n comment: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n addCommentToResponse(\n input.responseId,\n input.comment,\n ctx.user!.id\n )\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"0b0beac6-a26f-5bc1-becc-4071188968a9"}
|
|
1
|
+
{"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport {\n confirmDirectUpload,\n createDirectUploadFiles,\n updateUploadProgress,\n} from \"../lib/fileUpload.js\";\nimport {\n createTRPCRouter,\n protectedClassMemberProcedure,\n protectedProcedure,\n protectedTeacherProcedure,\n} from \"../trpc.js\";\nimport { z } from \"zod\";\nimport {\n getWorksheet,\n worksheetExists,\n listWorksheets,\n updateWorksheetRecord,\n deleteWorksheetRecord,\n createWorksheetRecord,\n createWorksheetFromPdf,\n createWorksheetFromUploadedPdf,\n addQuestionToWorksheet,\n reorderWorksheetQuestions,\n updateWorksheetQuestionRecord,\n deleteWorksheetQuestionRecord,\n getWorksheetSubmission,\n answerWorksheetQuestion,\n cancelGrading,\n regradeQuestion,\n gradeAnswer,\n addCommentToResponse,\n} from \"../services/worksheet.js\";\n\nconst directFileSchema = z.object({\n name: z.string(),\n type: z.string(),\n size: z.number(),\n});\n\nconst pdfFileSchema = directFileSchema.superRefine((file, ctx) => {\n const isPdf =\n file.type === \"application/pdf\" && file.name.toLowerCase().endsWith(\".pdf\");\n if (!isPdf) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Only PDF files are supported\",\n });\n }\n});\n\nconst getWorksheetUploadUrlsSchema = z.object({\n classId: z.string(),\n files: z.array(pdfFileSchema),\n});\n\nconst confirmWorksheetUploadSchema = z.object({\n classId: z.string(),\n fileId: z.string(),\n uploadSuccess: z.boolean(),\n errorMessage: z.string().optional(),\n});\n\nconst updateUploadProgressSchema = z.object({\n fileId: z.string(),\n progress: z.number().min(0).max(100),\n});\n\nexport const worksheetRouter = createTRPCRouter({\n getWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .query(({ ctx, input }) => getWorksheet(input.worksheetId, ctx.user!.id)),\n\n exists: protectedClassMemberProcedure\n .input(z.object({ id: z.string() }))\n .query(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n return worksheetExists(input.id);\n }),\n\n listWorksheets: protectedClassMemberProcedure\n .input(z.object({ classId: z.string() }))\n .query(({ input }) => listWorksheets(input.classId)),\n\n updateWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string(), name: z.string().optional() }))\n .mutation(({ ctx, input }) =>\n updateWorksheetRecord(input.worksheetId, ctx.user!.id, {\n name: input.name,\n })\n ),\n\n deleteWorksheet: protectedProcedure\n .input(z.object({ worksheetId: z.string() }))\n .mutation(({ ctx, input }) =>\n deleteWorksheetRecord(input.worksheetId, ctx.user!.id)\n ),\n\n create: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), name: z.string() }))\n .mutation(({ input }) =>\n createWorksheetRecord(input.classId, input.name)\n ),\n\n createFromPdf: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), url: z.string().url() }))\n .mutation(({ input }) => createWorksheetFromPdf(input.classId, input.url)),\n\n getWorksheetUploadUrls: protectedTeacherProcedure\n .input(getWorksheetUploadUrlsSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You must be logged in to upload files\",\n });\n }\n\n const uploadFiles = await createDirectUploadFiles(\n input.files,\n ctx.user.id\n );\n\n return {\n success: true,\n uploadFiles,\n };\n }),\n\n confirmWorksheetUpload: protectedTeacherProcedure\n .input(confirmWorksheetUploadSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You must be logged in\",\n });\n }\n\n const file = await prisma.file.findFirst({\n where: {\n id: input.fileId,\n userId: ctx.user.id,\n },\n });\n\n if (!file) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"File not found or you don't have permission\",\n });\n }\n\n await confirmDirectUpload(\n input.fileId,\n input.uploadSuccess,\n input.errorMessage\n );\n\n return {\n success: true,\n message: input.uploadSuccess\n ? \"Upload confirmed successfully\"\n : \"Upload failed\",\n };\n }),\n\n createFromUploadedPdf: protectedTeacherProcedure\n .input(z.object({ classId: z.string(), fileId: z.string() }))\n .mutation(({ ctx, input }) =>\n createWorksheetFromUploadedPdf(input.classId, input.fileId, ctx.user!.id)\n ),\n\n addQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z.enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ]),\n })\n )\n .mutation(({ ctx, input }) =>\n addQuestionToWorksheet(input.worksheetId, ctx.user!.id, {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n })\n ),\n\n reorderQuestions: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum([\"before\", \"after\"]),\n targetId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n reorderWorksheetQuestions(\n input.worksheetId,\n ctx.user!.id,\n input.movedId,\n input.position,\n input.targetId\n )\n ),\n\n updateQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(),\n markScheme: z.any().optional(),\n type: z\n .enum([\n \"MULTIPLE_CHOICE\",\n \"TRUE_FALSE\",\n \"SHORT_ANSWER\",\n \"LONG_ANSWER\",\n \"MATH_EXPRESSION\",\n \"ESSAY\",\n ])\n .optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n updateWorksheetQuestionRecord(\n input.worksheetId,\n input.questionId,\n ctx.user!.id,\n {\n question: input.question,\n answer: input.answer,\n points: input.points,\n options: input.options,\n markScheme: input.markScheme,\n type: input.type,\n }\n )\n ),\n\n deleteQuestion: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n deleteWorksheetQuestionRecord(\n input.worksheetId,\n input.questionId,\n ctx.user!.id\n )\n ),\n\n getWorksheetSubmission: protectedProcedure\n .input(\n z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n })\n )\n .query(({ ctx, input }) =>\n getWorksheetSubmission(input.worksheetId, input.submissionId, ctx.user!.id)\n ),\n\n answerQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n answerWorksheetQuestion(\n input.worksheetResponseId,\n input.questionId,\n input.response,\n ctx.user!.id\n )\n ),\n\n cancelGrading: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n cancelGrading(input.worksheetResponseId, input.progressId, ctx.user!.id)\n ),\n\n regradeQuestion: protectedProcedure\n .input(\n z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n regradeQuestion(input.worksheetResponseId, input.progressId, ctx.user!.id)\n ),\n\n gradeAnswer: protectedProcedure\n .input(\n z.object({\n questionId: z.string(),\n responseId: z.string().optional(),\n studentWorksheetResponseId: z.string(),\n response: z.string().optional(),\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n gradeAnswer(\n input.questionId,\n input.studentWorksheetResponseId,\n ctx.user!.id,\n {\n responseId: input.responseId,\n response: input.response,\n isCorrect: input.isCorrect,\n feedback: input.feedback,\n markschemeState: input.markschemeState,\n points: input.points,\n }\n )\n ),\n\n addComment: protectedProcedure\n .input(\n z.object({\n responseId: z.string(),\n comment: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n addCommentToResponse(\n input.responseId,\n input.comment,\n ctx.user!.id\n )\n ),\n\n updateUploadProgress: protectedProcedure\n .input(updateUploadProgressSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You must be logged in\",\n });\n }\n\n const file = await prisma.file.findFirst({\n where: {\n id: input.fileId,\n userId: ctx.user.id,\n },\n });\n\n if (!file) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"File not found or you don't have permission\",\n });\n }\n\n await updateUploadProgress(input.fileId, input.progress);\n\n return {\n success: true,\n progress: input.progress,\n };\n }),\n});\n"],"names":[],"mappings":"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","debug_id":"31932b12-1093-5e0f-a21c-e9301dcb8c25"}
|
|
@@ -24,6 +24,7 @@ export declare function listConversations(userId: string): Promise<{
|
|
|
24
24
|
conversationId: string;
|
|
25
25
|
role: import(".prisma/client").$Enums.ConversationRole;
|
|
26
26
|
joinedAt: Date;
|
|
27
|
+
hiddenAt: Date | null;
|
|
27
28
|
lastViewedAt: Date | null;
|
|
28
29
|
lastViewedMentionAt: Date | null;
|
|
29
30
|
})[];
|
|
@@ -47,6 +48,9 @@ export declare function listConversations(userId: string): Promise<{
|
|
|
47
48
|
unreadCount: number;
|
|
48
49
|
unreadMentionCount: number;
|
|
49
50
|
}[]>;
|
|
51
|
+
export declare function hideConversation(userId: string, conversationId: string): Promise<{
|
|
52
|
+
success: boolean;
|
|
53
|
+
}>;
|
|
50
54
|
/** Create a DM or group conversation with the given members. */
|
|
51
55
|
export declare function createConversationRecord(userId: string, type: "DM" | "GROUP", name: string | undefined, memberIds: string[]): Promise<{
|
|
52
56
|
members: ({
|
|
@@ -64,6 +68,7 @@ export declare function createConversationRecord(userId: string, type: "DM" | "G
|
|
|
64
68
|
conversationId: string;
|
|
65
69
|
role: import(".prisma/client").$Enums.ConversationRole;
|
|
66
70
|
joinedAt: Date;
|
|
71
|
+
hiddenAt: Date | null;
|
|
67
72
|
lastViewedAt: Date | null;
|
|
68
73
|
lastViewedMentionAt: Date | null;
|
|
69
74
|
})[];
|
|
@@ -91,6 +96,7 @@ export declare function getConversation(userId: string, conversationId: string):
|
|
|
91
96
|
conversationId: string;
|
|
92
97
|
role: import(".prisma/client").$Enums.ConversationRole;
|
|
93
98
|
joinedAt: Date;
|
|
99
|
+
hiddenAt: Date | null;
|
|
94
100
|
lastViewedAt: Date | null;
|
|
95
101
|
lastViewedMentionAt: Date | null;
|
|
96
102
|
})[];
|
|
@@ -118,6 +124,7 @@ export declare function addMemberToConversation(userId: string, conversationId:
|
|
|
118
124
|
conversationId: string;
|
|
119
125
|
role: import(".prisma/client").$Enums.ConversationRole;
|
|
120
126
|
joinedAt: Date;
|
|
127
|
+
hiddenAt: Date | null;
|
|
121
128
|
lastViewedAt: Date | null;
|
|
122
129
|
lastViewedMentionAt: Date | null;
|
|
123
130
|
})[];
|
|
@@ -145,6 +152,7 @@ export declare function removeMemberFromConversation(userId: string, conversatio
|
|
|
145
152
|
conversationId: string;
|
|
146
153
|
role: import(".prisma/client").$Enums.ConversationRole;
|
|
147
154
|
joinedAt: Date;
|
|
155
|
+
hiddenAt: Date | null;
|
|
148
156
|
lastViewedAt: Date | null;
|
|
149
157
|
lastViewedMentionAt: Date | null;
|
|
150
158
|
})[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.d.ts","sourceRoot":"/","sources":["services/conversation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"/","sources":["services/conversation.ts"],"names":[],"mappings":"AAmBA,gEAAgE;AAChE,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuDrD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;GAY5E;AAED,gEAAgE;AAChE,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,IAAI,GAAG,OAAO,EACpB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,SAAS,EAAE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEpB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;GAavB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BvB;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;GAejB"}
|
|
@@ -3,13 +3,20 @@
|
|
|
3
3
|
* Handles member management and unread counts.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
!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]="
|
|
6
|
+
!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]="1e016f9f-4be7-566a-a3f9-ad63c2a0ada1")}catch(e){}}();
|
|
7
7
|
import { TRPCError } from "@trpc/server";
|
|
8
|
-
import { findConversationsByUserId, countUnreadMessages, countUnreadMentions, findUserByUsername, findDmConversationsByUserId, findUsersByIdsOrUsernames, createConversation, findConversationByIdAndMember, createConversationMember, deleteConversationMember, } from "../models/conversation.js";
|
|
8
|
+
import { findConversationsByUserId, countUnreadMessages, countUnreadMentions, findUserByUsername, findDmConversationsByUserId, findUsersByIdsOrUsernames, createConversation, findConversationByIdAndMember, createConversationMember, hideConversationMember, deleteConversationMember, } from "../models/conversation.js";
|
|
9
9
|
/** List user's conversations with unread and mention counts. */
|
|
10
10
|
export async function listConversations(userId) {
|
|
11
11
|
const conversations = await findConversationsByUserId(userId);
|
|
12
|
-
const
|
|
12
|
+
const visibleConversations = conversations.filter((conversation) => {
|
|
13
|
+
const userMembership = conversation.members.find((member) => member.userId === userId);
|
|
14
|
+
if (!userMembership?.hiddenAt) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return conversation.updatedAt > userMembership.hiddenAt;
|
|
18
|
+
});
|
|
19
|
+
const conversationsWithUnread = await Promise.all(visibleConversations.map(async (conversation) => {
|
|
13
20
|
const userMembership = conversation.members.find((m) => m.userId === userId);
|
|
14
21
|
const lastViewedAt = userMembership?.lastViewedAt;
|
|
15
22
|
const lastViewedMentionAt = userMembership?.lastViewedMentionAt;
|
|
@@ -35,6 +42,17 @@ export async function listConversations(userId) {
|
|
|
35
42
|
}));
|
|
36
43
|
return conversationsWithUnread;
|
|
37
44
|
}
|
|
45
|
+
export async function hideConversation(userId, conversationId) {
|
|
46
|
+
const conversation = await findConversationByIdAndMember(conversationId, userId);
|
|
47
|
+
if (!conversation) {
|
|
48
|
+
throw new TRPCError({
|
|
49
|
+
code: "FORBIDDEN",
|
|
50
|
+
message: "Not a member of this conversation",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
await hideConversationMember(userId, conversationId);
|
|
54
|
+
return { success: true };
|
|
55
|
+
}
|
|
38
56
|
/** Create a DM or group conversation with the given members. */
|
|
39
57
|
export async function createConversationRecord(userId, type, name, memberIds) {
|
|
40
58
|
if (type === "GROUP" && !name) {
|
|
@@ -50,11 +68,11 @@ export async function createConversationRecord(userId, type, name, memberIds) {
|
|
|
50
68
|
});
|
|
51
69
|
}
|
|
52
70
|
if (type === "DM") {
|
|
53
|
-
const targetUser = await
|
|
71
|
+
const [targetUser] = await findUsersByIdsOrUsernames([memberIds[0]]);
|
|
54
72
|
if (!targetUser) {
|
|
55
73
|
throw new TRPCError({
|
|
56
74
|
code: "BAD_REQUEST",
|
|
57
|
-
message: `User
|
|
75
|
+
message: `User not found`,
|
|
58
76
|
});
|
|
59
77
|
}
|
|
60
78
|
const existingDMs = await findDmConversationsByUserId(userId);
|
|
@@ -135,4 +153,4 @@ export async function removeMemberFromConversation(userId, conversationId, membe
|
|
|
135
153
|
return conversation;
|
|
136
154
|
}
|
|
137
155
|
//# sourceMappingURL=conversation.js.map
|
|
138
|
-
//# debugId=
|
|
156
|
+
//# debugId=1e016f9f-4be7-566a-a3f9-ad63c2a0ada1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.js","sources":["services/conversation.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Conversation service – list, create, and manage DM/group conversations.\n * Handles member management and unread counts.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport {\n findConversationsByUserId,\n countUnreadMessages,\n countUnreadMentions,\n findUserByUsername,\n findDmConversationsByUserId,\n findUsersByIdsOrUsernames,\n createConversation,\n findConversationByIdAndMember,\n createConversationMember,\n deleteConversationMember,\n} from \"../models/conversation.js\";\n\n/** List user's conversations with unread and mention counts. */\nexport async function listConversations(userId: string) {\n const conversations = await findConversationsByUserId(userId);\n\n const conversationsWithUnread = await Promise.all(\n conversations.map(async (conversation) => {\n const userMembership = conversation.members.find(\n (m) => m.userId === userId\n );\n const lastViewedAt = userMembership?.lastViewedAt;\n const lastViewedMentionAt = userMembership?.lastViewedMentionAt;\n\n const unreadCount = await countUnreadMessages(\n conversation.id,\n userId,\n lastViewedAt ?? undefined\n );\n\n const mentionCutoffTime =\n lastViewedMentionAt && lastViewedAt\n ? lastViewedMentionAt > lastViewedAt\n ? lastViewedMentionAt\n : lastViewedAt\n : lastViewedMentionAt || lastViewedAt;\n\n const unreadMentionCount = await countUnreadMentions(\n conversation.id,\n userId,\n mentionCutoffTime ?? undefined\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 a DM or group conversation with the given members. */\nexport async function createConversationRecord(\n userId: string,\n type: \"DM\" | \"GROUP\",\n name: string | undefined,\n memberIds: string[]\n) {\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 if (type === \"DM\") {\n const targetUser = await findUserByUsername(memberIds[0]);\n if (!targetUser) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: `User \"${memberIds[0]}\" not found`,\n });\n }\n\n const existingDMs = await findDmConversationsByUserId(userId);\n const existingDM = existingDMs.find((conv) => {\n const memberUserIds = conv.members.map((m) => m.userId);\n return (\n memberUserIds.length === 2 &&\n memberUserIds.includes(userId) &&\n memberUserIds.includes(targetUser.id)\n );\n });\n\n if (existingDM) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: `A conversation with ${targetUser.username} already exists`,\n });\n }\n }\n\n const members = await findUsersByIdsOrUsernames(memberIds);\n type Member = (typeof members)[number];\n const uniqueMembers = Array.from(\n new Map(members.map((m) => [m.id, m] as [string, Member])).values()\n );\n\n if (uniqueMembers.length !== memberIds.length) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"One or more members not found\",\n });\n }\n\n const toAddIds = memberIds\n .map((id) =>\n uniqueMembers.find((m) => m.id === id || m.username === id)?.id\n )\n .filter(Boolean) as string[];\n\n return createConversation({\n type,\n name,\n members: [\n { userId, role: type === \"GROUP\" ? \"ADMIN\" : \"MEMBER\" },\n ...toAddIds.map((uid) => ({ userId: uid, role: \"MEMBER\" })),\n ],\n });\n}\n\nexport async function getConversation(\n userId: string,\n conversationId: string\n) {\n const conversation = await findConversationByIdAndMember(\n conversationId,\n userId\n );\n if (!conversation) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Conversation not found or access denied\",\n });\n }\n return conversation;\n}\n\nexport async function addMemberToConversation(\n userId: string,\n conversationId: string,\n memberUsername: string\n) {\n const conversation = await findConversationByIdAndMember(\n conversationId,\n userId\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 findUserByUsername(memberUsername);\n if (!member) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Member not found\",\n });\n }\n\n await createConversationMember({\n userId: member.id,\n conversationId,\n role: \"MEMBER\",\n });\n\n return conversation;\n}\n\nexport async function removeMemberFromConversation(\n userId: string,\n conversationId: string,\n memberId: string\n) {\n const conversation = await findConversationByIdAndMember(\n conversationId,\n userId\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 deleteConversationMember(memberId, conversationId);\n return conversation;\n}\n"],"names":[],"mappings":"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","debug_id":"4ed19abe-3dc1-5bea-9dac-6a700dc76438"}
|
|
1
|
+
{"version":3,"file":"conversation.js","sources":["services/conversation.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Conversation service – list, create, and manage DM/group conversations.\n * Handles member management and unread counts.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport {\n findConversationsByUserId,\n countUnreadMessages,\n countUnreadMentions,\n findUserByUsername,\n findDmConversationsByUserId,\n findUsersByIdsOrUsernames,\n createConversation,\n findConversationByIdAndMember,\n createConversationMember,\n hideConversationMember,\n deleteConversationMember,\n} from \"../models/conversation.js\";\n\n/** List user's conversations with unread and mention counts. */\nexport async function listConversations(userId: string) {\n const conversations = await findConversationsByUserId(userId);\n const visibleConversations = conversations.filter((conversation) => {\n const userMembership = conversation.members.find((member) => member.userId === userId);\n\n if (!userMembership?.hiddenAt) {\n return true;\n }\n\n return conversation.updatedAt > userMembership.hiddenAt;\n });\n\n const conversationsWithUnread = await Promise.all(\n visibleConversations.map(async (conversation) => {\n const userMembership = conversation.members.find(\n (m) => m.userId === userId\n );\n const lastViewedAt = userMembership?.lastViewedAt;\n const lastViewedMentionAt = userMembership?.lastViewedMentionAt;\n\n const unreadCount = await countUnreadMessages(\n conversation.id,\n userId,\n lastViewedAt ?? undefined\n );\n\n const mentionCutoffTime =\n lastViewedMentionAt && lastViewedAt\n ? lastViewedMentionAt > lastViewedAt\n ? lastViewedMentionAt\n : lastViewedAt\n : lastViewedMentionAt || lastViewedAt;\n\n const unreadMentionCount = await countUnreadMentions(\n conversation.id,\n userId,\n mentionCutoffTime ?? undefined\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\nexport async function hideConversation(userId: string, conversationId: string) {\n const conversation = await findConversationByIdAndMember(conversationId, userId);\n if (!conversation) {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"Not a member of this conversation\",\n });\n }\n\n await hideConversationMember(userId, conversationId);\n\n return { success: true };\n}\n\n/** Create a DM or group conversation with the given members. */\nexport async function createConversationRecord(\n userId: string,\n type: \"DM\" | \"GROUP\",\n name: string | undefined,\n memberIds: string[]\n) {\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 if (type === \"DM\") {\n const [targetUser] = await findUsersByIdsOrUsernames([memberIds[0]]);\n if (!targetUser) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: `User not found`,\n });\n }\n\n const existingDMs = await findDmConversationsByUserId(userId);\n const existingDM = existingDMs.find((conv) => {\n const memberUserIds = conv.members.map((m) => m.userId);\n return (\n memberUserIds.length === 2 &&\n memberUserIds.includes(userId) &&\n memberUserIds.includes(targetUser.id)\n );\n });\n\n if (existingDM) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: `A conversation with ${targetUser.username} already exists`,\n });\n }\n }\n\n const members = await findUsersByIdsOrUsernames(memberIds);\n type Member = (typeof members)[number];\n const uniqueMembers = Array.from(\n new Map(members.map((m) => [m.id, m] as [string, Member])).values()\n );\n\n if (uniqueMembers.length !== memberIds.length) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"One or more members not found\",\n });\n }\n\n const toAddIds = memberIds\n .map((id) =>\n uniqueMembers.find((m) => m.id === id || m.username === id)?.id\n )\n .filter(Boolean) as string[];\n\n return createConversation({\n type,\n name,\n members: [\n { userId, role: type === \"GROUP\" ? \"ADMIN\" : \"MEMBER\" },\n ...toAddIds.map((uid) => ({ userId: uid, role: \"MEMBER\" })),\n ],\n });\n}\n\nexport async function getConversation(\n userId: string,\n conversationId: string\n) {\n const conversation = await findConversationByIdAndMember(\n conversationId,\n userId\n );\n if (!conversation) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Conversation not found or access denied\",\n });\n }\n return conversation;\n}\n\nexport async function addMemberToConversation(\n userId: string,\n conversationId: string,\n memberUsername: string\n) {\n const conversation = await findConversationByIdAndMember(\n conversationId,\n userId\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 findUserByUsername(memberUsername);\n if (!member) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Member not found\",\n });\n }\n\n await createConversationMember({\n userId: member.id,\n conversationId,\n role: \"MEMBER\",\n });\n\n return conversation;\n}\n\nexport async function removeMemberFromConversation(\n userId: string,\n conversationId: string,\n memberId: string\n) {\n const conversation = await findConversationByIdAndMember(\n conversationId,\n userId\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 deleteConversationMember(memberId, conversationId);\n return conversation;\n}\n"],"names":[],"mappings":"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","debug_id":"1e016f9f-4be7-566a-a3f9-ad63c2a0ada1"}
|
|
@@ -26,6 +26,7 @@ export declare function createLabChat(userId: string, input: {
|
|
|
26
26
|
conversationId: string;
|
|
27
27
|
role: import(".prisma/client").$Enums.ConversationRole;
|
|
28
28
|
joinedAt: Date;
|
|
29
|
+
hiddenAt: Date | null;
|
|
29
30
|
lastViewedAt: Date | null;
|
|
30
31
|
lastViewedMentionAt: Date | null;
|
|
31
32
|
})[];
|
|
@@ -78,6 +79,7 @@ export declare function getLabChat(userId: string, labChatId: string): Promise<{
|
|
|
78
79
|
conversationId: string;
|
|
79
80
|
role: import(".prisma/client").$Enums.ConversationRole;
|
|
80
81
|
joinedAt: Date;
|
|
82
|
+
hiddenAt: Date | null;
|
|
81
83
|
lastViewedAt: Date | null;
|
|
82
84
|
lastViewedMentionAt: Date | null;
|
|
83
85
|
})[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labChat.d.ts","sourceRoot":"/","sources":["services/labChat.ts"],"names":[],"mappings":"AA2BA,sFAAsF;AACtF,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE
|
|
1
|
+
{"version":3,"file":"labChat.d.ts","sourceRoot":"/","sources":["services/labChat.ts"],"names":[],"mappings":"AA2BA,sFAAsF;AACtF,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsH3D;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCjE;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqBjE;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;;;;;;;;;;;;;;;;;;;;GAuIF;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;GAiDpE;AAED,8FAA8F;AAC9F,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;GAiFxE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"/","sources":["services/message.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAmB7C,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAM,EAAO,QAQvB;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,MAAM,CAAC,iBAAiB,EAC5B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,MAAM,EAAO,iBA2BvB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD,8DAmBF;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;;;GAuCF;AAED,oEAAoE;AACpE,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;;;;;;;;;;;;;;;;;;;;cAoCyB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;GAMlD;AAED,oFAAoF;AACpF,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"/","sources":["services/message.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAmB7C,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAM,EAAO,QAQvB;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,MAAM,CAAC,iBAAiB,EAC5B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,MAAM,EAAO,iBA2BvB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD,8DAmBF;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;;;GAuCF;AAED,oEAAoE;AACpE,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;;;;;;;;;;;;;;;;;;;;cAoCyB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;;GAMlD;AAED,oFAAoF;AACpF,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;;;;;;;;;;;;;;;;;;;;GAgIF;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;;;;;;;;;;;;;;;GAmHF;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;GAuDpE;AAUD,mFAAmF;AACnF,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;;GA6HF;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;GA+BtE;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM;;GAgCvB;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM;;;GA8BvB"}
|
package/dist/services/message.js
CHANGED
|
@@ -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]="
|
|
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]="181d07f5-4bad-5e9c-a71e-3c354adb855b")}catch(e){}}();
|
|
3
3
|
import { TRPCError } from "@trpc/server";
|
|
4
4
|
import { prisma } from "../lib/prisma.js";
|
|
5
5
|
import { chatChannel, pusher } from "../lib/pusher.js";
|
|
@@ -156,6 +156,13 @@ export async function sendMessage(userId, input) {
|
|
|
156
156
|
})),
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
|
+
await tx.conversationMember.updateMany({
|
|
160
|
+
where: {
|
|
161
|
+
conversationId,
|
|
162
|
+
hiddenAt: { not: null },
|
|
163
|
+
},
|
|
164
|
+
data: { hiddenAt: null },
|
|
165
|
+
});
|
|
159
166
|
await tx.conversation.update({
|
|
160
167
|
where: { id: conversationId },
|
|
161
168
|
data: { updatedAt: new Date() },
|
|
@@ -537,4 +544,4 @@ export async function getUnreadCount(userId, conversationId) {
|
|
|
537
544
|
return { unreadCount, unreadMentionCount };
|
|
538
545
|
}
|
|
539
546
|
//# sourceMappingURL=message.js.map
|
|
540
|
-
//# debugId=
|
|
547
|
+
//# debugId=181d07f5-4bad-5e9c-a71e-3c354adb855b
|