@studious-lms/server 1.8.0 → 1.11.0
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/dist/middleware/security.d.ts.map +1 -1
- package/dist/middleware/security.js +3 -3
- package/dist/middleware/security.js.map +1 -1
- package/dist/models/agenda.d.ts +2 -2
- package/dist/models/announcement.d.ts +2 -2
- package/dist/models/assignment.d.ts +33 -33
- package/dist/models/class.d.ts +2 -2
- package/dist/models/cloudStorage.d.ts +14 -1
- package/dist/models/cloudStorage.d.ts.map +1 -1
- package/dist/models/cloudStorage.js +123 -3
- package/dist/models/cloudStorage.js.map +1 -1
- package/dist/models/event.d.ts +3 -3
- package/dist/models/file.d.ts +27 -26
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/file.js +4 -39
- package/dist/models/file.js.map +1 -1
- package/dist/models/labChat.d.ts +6 -6
- package/dist/models/section.d.ts +1 -1
- package/dist/routers/_app.d.ts +444 -100
- 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/agenda.d.ts +2 -2
- package/dist/routers/assignment.d.ts +31 -31
- package/dist/routers/class.d.ts +5 -5
- package/dist/routers/event.d.ts +2 -2
- package/dist/routers/file.d.ts +2 -2
- package/dist/routers/folder.d.ts +24 -0
- package/dist/routers/folder.d.ts.map +1 -1
- package/dist/routers/folder.js +27 -5
- package/dist/routers/folder.js.map +1 -1
- package/dist/routers/labChat.d.ts +2 -2
- package/dist/routers/newtonChat.d.ts +1 -1
- package/dist/routers/permissions.d.ts +120 -0
- package/dist/routers/permissions.d.ts.map +1 -0
- package/dist/routers/permissions.js +50 -0
- package/dist/routers/permissions.js.map +1 -0
- package/dist/routers/studentProgress.d.ts +45 -0
- package/dist/routers/studentProgress.d.ts.map +1 -1
- package/dist/routers/studentProgress.js +12 -3
- package/dist/routers/studentProgress.js.map +1 -1
- package/dist/routers/tag.d.ts +5 -5
- package/dist/services/agenda.d.ts +2 -2
- package/dist/services/assignment.d.ts +31 -31
- package/dist/services/class.d.ts +5 -5
- package/dist/services/class.js +3 -3
- package/dist/services/class.js.map +1 -1
- package/dist/services/event.d.ts +2 -2
- package/dist/services/file.d.ts +22 -5
- package/dist/services/file.d.ts.map +1 -1
- package/dist/services/file.js +81 -45
- package/dist/services/file.js.map +1 -1
- package/dist/services/folder.d.ts +97 -2
- package/dist/services/folder.d.ts.map +1 -1
- package/dist/services/folder.js +158 -87
- package/dist/services/folder.js.map +1 -1
- package/dist/services/labChat.d.ts +2 -2
- package/dist/services/permissions.d.ts +188 -0
- package/dist/services/permissions.d.ts.map +1 -0
- package/dist/services/permissions.js +661 -0
- package/dist/services/permissions.js.map +1 -0
- package/dist/services/studentProgress.d.ts +94 -0
- package/dist/services/studentProgress.d.ts.map +1 -1
- package/dist/services/studentProgress.js +94 -3
- package/dist/services/studentProgress.js.map +1 -1
- package/package.json +1 -1
- package/prisma/migrations/20260510170000_add_folder_permissions/migration.sql +93 -0
- package/prisma/schema.prisma +74 -0
- package/src/middleware/security.ts +1 -1
- package/src/models/cloudStorage.ts +134 -1
- package/src/models/file.ts +2 -37
- package/src/routers/_app.ts +2 -0
- package/src/routers/folder.ts +32 -2
- package/src/routers/permissions.ts +71 -0
- package/src/routers/studentProgress.ts +21 -0
- package/src/services/class.ts +1 -1
- package/src/services/file.ts +76 -47
- package/src/services/folder.ts +180 -91
- package/src/services/permissions.ts +778 -0
- package/src/services/studentProgress.ts +197 -11
- package/tests/unit/services/permissions.test.ts +463 -0
- package/tests/unit/services/studentProgress.test.ts +168 -2
package/dist/routers/folder.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export declare const folderRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
30
30
|
} | {
|
|
31
31
|
userId: string;
|
|
32
32
|
kind: "PERSONAL";
|
|
33
|
+
} | {
|
|
34
|
+
kind: "SHARED_WITH_ME";
|
|
33
35
|
};
|
|
34
36
|
};
|
|
35
37
|
output: {
|
|
@@ -75,6 +77,23 @@ export declare const folderRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
75
77
|
}[];
|
|
76
78
|
canWrite: boolean;
|
|
77
79
|
scope: import("../models/cloudStorage.js").CloudScope;
|
|
80
|
+
displayRoot: {
|
|
81
|
+
kind: "SHARED_WITH_ME";
|
|
82
|
+
name: string;
|
|
83
|
+
} | null;
|
|
84
|
+
};
|
|
85
|
+
meta: object;
|
|
86
|
+
}>;
|
|
87
|
+
/** Top-most folders/files explicitly shared with the caller (Drive-style). */
|
|
88
|
+
listSharedWithMe: import("@trpc/server").TRPCQueryProcedure<{
|
|
89
|
+
input: void;
|
|
90
|
+
output: {
|
|
91
|
+
folders: {
|
|
92
|
+
id: string;
|
|
93
|
+
name: string;
|
|
94
|
+
color: string | null;
|
|
95
|
+
}[];
|
|
96
|
+
files: never[];
|
|
78
97
|
};
|
|
79
98
|
meta: object;
|
|
80
99
|
}>;
|
|
@@ -100,6 +119,11 @@ export declare const folderRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
100
119
|
color: string | null;
|
|
101
120
|
section: string;
|
|
102
121
|
}[];
|
|
122
|
+
sharedWithMe: {
|
|
123
|
+
kind: "SHARED_WITH_ME";
|
|
124
|
+
folderCount: number;
|
|
125
|
+
fileCount: number;
|
|
126
|
+
};
|
|
103
127
|
};
|
|
104
128
|
meta: object;
|
|
105
129
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.d.ts","sourceRoot":"/","sources":["routers/folder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"folder.d.ts","sourceRoot":"/","sources":["routers/folder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyDxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;IACvB,wEAAwE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoBxE,8EAA8E;;;;;;;;;;;;;IAK9E,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAKnE,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiE/C,uDAAuD;;;;;;;;;;;;;IAevD,yDAAyD;;;;;;;;;;;;GAgBzD,CAAC"}
|
package/dist/routers/folder.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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]="f76c8e6f-19ba-5dd6-9a07-530a455a8b5f")}catch(e){}}();
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { createTRPCRouter, protectedProcedure, } from "../trpc.js";
|
|
5
|
-
import { browseFolder, confirmFolderUpload, createFolderRecord, deleteFolder, getFolder, getFolderParents, getFolderUploadUrls, getRootFolder, listUserScopes, moveFolder, updateFolderRecord, } from "../services/folder.js";
|
|
5
|
+
import { browseFolder, browseSharedWithMe, confirmFolderUpload, createFolderRecord, deleteFolder, getFolder, getFolderParents, getFolderUploadUrls, getRootFolder, listUserScopes, moveFolder, updateFolderRecord, } from "../services/folder.js";
|
|
6
|
+
import { listSharedWithMe } from "../services/permissions.js";
|
|
6
7
|
const directFileSchema = z.object({
|
|
7
8
|
name: z.string(),
|
|
8
9
|
type: z.string(),
|
|
@@ -24,14 +25,35 @@ const cloudScopeSchema = z.discriminatedUnion("kind", [
|
|
|
24
25
|
z.object({ kind: z.literal("SCHOOL_STORAGE"), schoolId: z.string() }),
|
|
25
26
|
z.object({ kind: z.literal("PERSONAL"), userId: z.string() }),
|
|
26
27
|
]);
|
|
28
|
+
/**
|
|
29
|
+
* Extended scope schema for `browse` only. SHARED_WITH_ME is a *virtual*
|
|
30
|
+
* scope — it has no root row in the `Folder` table and you can't create
|
|
31
|
+
* folders inside it directly. It just collects every top-most explicit grant
|
|
32
|
+
* the user holds for "Shared with me"-style display.
|
|
33
|
+
*/
|
|
34
|
+
const browseScopeSchema = z.discriminatedUnion("kind", [
|
|
35
|
+
z.object({ kind: z.literal("CLASS"), classId: z.string() }),
|
|
36
|
+
z.object({ kind: z.literal("SCHOOL_STORAGE"), schoolId: z.string() }),
|
|
37
|
+
z.object({ kind: z.literal("PERSONAL"), userId: z.string() }),
|
|
38
|
+
z.object({ kind: z.literal("SHARED_WITH_ME") }),
|
|
39
|
+
]);
|
|
27
40
|
export const folderRouter = createTRPCRouter({
|
|
28
41
|
/** Browse a folder (or scope root) with breadcrumbs and access flag. */
|
|
29
42
|
browse: protectedProcedure
|
|
30
43
|
.input(z.union([
|
|
31
44
|
z.object({ folderId: z.string() }),
|
|
32
|
-
z.object({ scope:
|
|
45
|
+
z.object({ scope: browseScopeSchema }),
|
|
33
46
|
]))
|
|
34
|
-
.query(({ ctx, input }) =>
|
|
47
|
+
.query(({ ctx, input }) => {
|
|
48
|
+
if ("scope" in input && input.scope.kind === "SHARED_WITH_ME") {
|
|
49
|
+
return browseSharedWithMe(ctx.user.id);
|
|
50
|
+
}
|
|
51
|
+
return browseFolder(ctx.user.id, "scope" in input
|
|
52
|
+
? { scope: input.scope }
|
|
53
|
+
: input);
|
|
54
|
+
}),
|
|
55
|
+
/** Top-most folders/files explicitly shared with the caller (Drive-style). */
|
|
56
|
+
listSharedWithMe: protectedProcedure.query(({ ctx }) => listSharedWithMe(ctx.user.id)),
|
|
35
57
|
/** What scopes can this user pick from in the cloud-storage UI? */
|
|
36
58
|
listScopes: protectedProcedure.query(({ ctx }) => listUserScopes(ctx.user.id)),
|
|
37
59
|
/** Root folder for any scope (no folderId). */
|
|
@@ -104,4 +126,4 @@ export const folderRouter = createTRPCRouter({
|
|
|
104
126
|
})),
|
|
105
127
|
});
|
|
106
128
|
//# sourceMappingURL=folder.js.map
|
|
107
|
-
//# debugId=
|
|
129
|
+
//# debugId=f76c8e6f-19ba-5dd6-9a07-530a455a8b5f
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"folder.js","sources":["routers/folder.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport {\n createTRPCRouter,\n protectedProcedure,\n} from \"../trpc.js\";\nimport {\n browseFolder,\n confirmFolderUpload,\n createFolderRecord,\n deleteFolder,\n getFolder,\n getFolderParents,\n getFolderUploadUrls,\n getRootFolder,\n listUserScopes,\n moveFolder,\n updateFolderRecord,\n} from \"../services/folder.js\";\n\nconst directFileSchema = z.object({\n name: z.string(),\n type: z.string(),\n size: z.number(),\n});\n\n/**\n * Cloud scope discriminator. Folders live under one of:\n * - CLASS: a class shared-files area\n * - SCHOOL_STORAGE: institution-wide files\n * - PERSONAL: a single user's storage\n *\n * All folder operations identify the location they apply to with either a\n * `folderId` (for an existing folder) or a `scope` (when no folder exists yet,\n * e.g. browsing a scope root). There is no `classId` shorthand — use\n * `{ scope: { kind: \"CLASS\", classId } }` instead.\n */\nconst cloudScopeSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"CLASS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"SCHOOL_STORAGE\"), schoolId: z.string() }),\n z.object({ kind: z.literal(\"PERSONAL\"), userId: z.string() }),\n]);\n\nexport const folderRouter = createTRPCRouter({\n /** Browse a folder (or scope root) with breadcrumbs and access flag. */\n browse: protectedProcedure\n .input(\n z.union([\n z.object({ folderId: z.string() }),\n z.object({ scope: cloudScopeSchema }),\n ])\n )\n .query(({ ctx, input }) => browseFolder(ctx.user!.id, input)),\n\n /** What scopes can this user pick from in the cloud-storage UI? */\n listScopes: protectedProcedure.query(({ ctx }) =>\n listUserScopes(ctx.user!.id)\n ),\n\n /** Root folder for any scope (no folderId). */\n getRootFolder: protectedProcedure\n .input(z.object({ scope: cloudScopeSchema }))\n .query(({ ctx, input }) => getRootFolder(ctx.user!.id, input.scope)),\n\n get: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) => getFolder(ctx.user!.id, input.folderId)),\n\n getParents: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) => getFolderParents(ctx.user!.id, input.folderId)),\n\n create: protectedProcedure\n .input(\n z.object({\n name: z.string().min(1),\n parentFolderId: z.string().nullable().optional(),\n color: z.string().optional(),\n scope: cloudScopeSchema.optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n createFolderRecord(ctx.user!.id, {\n name: input.name,\n parentFolderId: input.parentFolderId ?? undefined,\n color: input.color,\n scope: input.scope,\n })\n ),\n\n update: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n name: z.string().optional(),\n color: z.string().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n updateFolderRecord(ctx.user!.id, {\n folderId: input.folderId,\n name: input.name,\n color: input.color,\n })\n ),\n\n delete: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .mutation(({ ctx, input }) => deleteFolder(ctx.user!.id, input.folderId)),\n\n move: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n targetParentFolderId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n moveFolder(ctx.user!.id, {\n folderId: input.folderId,\n targetParentFolderId: input.targetParentFolderId,\n })\n ),\n\n /** Get signed upload URLs for direct-to-GCS upload. */\n getFolderUploadUrls: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n files: z.array(directFileSchema),\n })\n )\n .mutation(({ ctx, input }) =>\n getFolderUploadUrls(ctx.user!.id, {\n folderId: input.folderId,\n files: input.files,\n })\n ),\n\n /** Acknowledge a direct upload completed (or failed). */\n confirmFolderUpload: protectedProcedure\n .input(\n z.object({\n fileId: z.string(),\n uploadSuccess: z.boolean(),\n errorMessage: z.string().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n confirmFolderUpload(ctx.user!.id, {\n fileId: input.fileId,\n uploadSuccess: input.uploadSuccess,\n errorMessage: input.errorMessage,\n })\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"9f777a4d-302d-516f-8d82-00a1ba3392ab"}
|
|
1
|
+
{"version":3,"file":"folder.js","sources":["routers/folder.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport {\n createTRPCRouter,\n protectedProcedure,\n} from \"../trpc.js\";\nimport {\n browseFolder,\n browseSharedWithMe,\n confirmFolderUpload,\n createFolderRecord,\n deleteFolder,\n getFolder,\n getFolderParents,\n getFolderUploadUrls,\n getRootFolder,\n listUserScopes,\n moveFolder,\n updateFolderRecord,\n} from \"../services/folder.js\";\nimport { listSharedWithMe } from \"../services/permissions.js\";\n\nconst directFileSchema = z.object({\n name: z.string(),\n type: z.string(),\n size: z.number(),\n});\n\n/**\n * Cloud scope discriminator. Folders live under one of:\n * - CLASS: a class shared-files area\n * - SCHOOL_STORAGE: institution-wide files\n * - PERSONAL: a single user's storage\n *\n * All folder operations identify the location they apply to with either a\n * `folderId` (for an existing folder) or a `scope` (when no folder exists yet,\n * e.g. browsing a scope root). There is no `classId` shorthand — use\n * `{ scope: { kind: \"CLASS\", classId } }` instead.\n */\nconst cloudScopeSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"CLASS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"SCHOOL_STORAGE\"), schoolId: z.string() }),\n z.object({ kind: z.literal(\"PERSONAL\"), userId: z.string() }),\n]);\n\n/**\n * Extended scope schema for `browse` only. SHARED_WITH_ME is a *virtual*\n * scope — it has no root row in the `Folder` table and you can't create\n * folders inside it directly. It just collects every top-most explicit grant\n * the user holds for \"Shared with me\"-style display.\n */\nconst browseScopeSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"CLASS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"SCHOOL_STORAGE\"), schoolId: z.string() }),\n z.object({ kind: z.literal(\"PERSONAL\"), userId: z.string() }),\n z.object({ kind: z.literal(\"SHARED_WITH_ME\") }),\n]);\n\nexport const folderRouter = createTRPCRouter({\n /** Browse a folder (or scope root) with breadcrumbs and access flag. */\n browse: protectedProcedure\n .input(\n z.union([\n z.object({ folderId: z.string() }),\n z.object({ scope: browseScopeSchema }),\n ])\n )\n .query(({ ctx, input }) => {\n if (\"scope\" in input && input.scope.kind === \"SHARED_WITH_ME\") {\n return browseSharedWithMe(ctx.user!.id);\n }\n return browseFolder(\n ctx.user!.id,\n \"scope\" in input\n ? { scope: input.scope as Exclude<typeof input.scope, { kind: \"SHARED_WITH_ME\" }> }\n : input\n );\n }),\n\n /** Top-most folders/files explicitly shared with the caller (Drive-style). */\n listSharedWithMe: protectedProcedure.query(({ ctx }) =>\n listSharedWithMe(ctx.user!.id)\n ),\n\n /** What scopes can this user pick from in the cloud-storage UI? */\n listScopes: protectedProcedure.query(({ ctx }) =>\n listUserScopes(ctx.user!.id)\n ),\n\n /** Root folder for any scope (no folderId). */\n getRootFolder: protectedProcedure\n .input(z.object({ scope: cloudScopeSchema }))\n .query(({ ctx, input }) => getRootFolder(ctx.user!.id, input.scope)),\n\n get: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) => getFolder(ctx.user!.id, input.folderId)),\n\n getParents: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) => getFolderParents(ctx.user!.id, input.folderId)),\n\n create: protectedProcedure\n .input(\n z.object({\n name: z.string().min(1),\n parentFolderId: z.string().nullable().optional(),\n color: z.string().optional(),\n scope: cloudScopeSchema.optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n createFolderRecord(ctx.user!.id, {\n name: input.name,\n parentFolderId: input.parentFolderId ?? undefined,\n color: input.color,\n scope: input.scope,\n })\n ),\n\n update: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n name: z.string().optional(),\n color: z.string().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n updateFolderRecord(ctx.user!.id, {\n folderId: input.folderId,\n name: input.name,\n color: input.color,\n })\n ),\n\n delete: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .mutation(({ ctx, input }) => deleteFolder(ctx.user!.id, input.folderId)),\n\n move: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n targetParentFolderId: z.string(),\n })\n )\n .mutation(({ ctx, input }) =>\n moveFolder(ctx.user!.id, {\n folderId: input.folderId,\n targetParentFolderId: input.targetParentFolderId,\n })\n ),\n\n /** Get signed upload URLs for direct-to-GCS upload. */\n getFolderUploadUrls: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n files: z.array(directFileSchema),\n })\n )\n .mutation(({ ctx, input }) =>\n getFolderUploadUrls(ctx.user!.id, {\n folderId: input.folderId,\n files: input.files,\n })\n ),\n\n /** Acknowledge a direct upload completed (or failed). */\n confirmFolderUpload: protectedProcedure\n .input(\n z.object({\n fileId: z.string(),\n uploadSuccess: z.boolean(),\n errorMessage: z.string().optional(),\n })\n )\n .mutation(({ ctx, input }) =>\n confirmFolderUpload(ctx.user!.id, {\n fileId: input.fileId,\n uploadSuccess: input.uploadSuccess,\n errorMessage: input.errorMessage,\n })\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"f76c8e6f-19ba-5dd6-9a07-530a455a8b5f"}
|
|
@@ -69,8 +69,8 @@ export declare const labChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
69
69
|
id: string;
|
|
70
70
|
createdAt: Date;
|
|
71
71
|
updatedAt: Date;
|
|
72
|
-
conversationId: string;
|
|
73
72
|
classId: string;
|
|
73
|
+
conversationId: string;
|
|
74
74
|
title: string;
|
|
75
75
|
createdById: string;
|
|
76
76
|
};
|
|
@@ -128,8 +128,8 @@ export declare const labChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
128
128
|
id: string;
|
|
129
129
|
createdAt: Date;
|
|
130
130
|
updatedAt: Date;
|
|
131
|
-
conversationId: string;
|
|
132
131
|
classId: string;
|
|
132
|
+
conversationId: string;
|
|
133
133
|
title: string;
|
|
134
134
|
createdById: string;
|
|
135
135
|
};
|
|
@@ -18,8 +18,8 @@ export declare const newtonChatRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
18
18
|
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
19
19
|
getTutorConversation: import("@trpc/server").TRPCQueryProcedure<{
|
|
20
20
|
input: {
|
|
21
|
-
assignmentId: string;
|
|
22
21
|
classId: string;
|
|
22
|
+
assignmentId: string;
|
|
23
23
|
};
|
|
24
24
|
output: {
|
|
25
25
|
conversationId: string;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permissions router. Backs the "Share" dialog and the "Shared with me" view.
|
|
3
|
+
*
|
|
4
|
+
* Permission semantics live in `services/permissions.ts`; this router is just
|
|
5
|
+
* a thin Zod-validated tRPC surface over those helpers.
|
|
6
|
+
*
|
|
7
|
+
* v1 grants only on folders. Files inherit from their parent folder. Adding
|
|
8
|
+
* file-level grants later is a non-breaking, additive change.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { type PermissionPrincipalInput } from "../services/permissions.js";
|
|
12
|
+
export declare const permissionsRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
13
|
+
ctx: import("../trpc.js").Context;
|
|
14
|
+
meta: object;
|
|
15
|
+
errorShape: {
|
|
16
|
+
data: {
|
|
17
|
+
zodError: z.typeToFlattenedError<any, string> | null;
|
|
18
|
+
prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
|
|
19
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
20
|
+
httpStatus: number;
|
|
21
|
+
path?: string;
|
|
22
|
+
stack?: string;
|
|
23
|
+
};
|
|
24
|
+
message: string;
|
|
25
|
+
code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
|
|
26
|
+
};
|
|
27
|
+
transformer: false;
|
|
28
|
+
}, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
|
|
29
|
+
/** List all explicit grants on a folder. Caller must have WRITE. */
|
|
30
|
+
list: import("@trpc/server").TRPCQueryProcedure<{
|
|
31
|
+
input: {
|
|
32
|
+
folderId: string;
|
|
33
|
+
};
|
|
34
|
+
output: ({
|
|
35
|
+
school: {
|
|
36
|
+
name: string;
|
|
37
|
+
id: string;
|
|
38
|
+
} | null;
|
|
39
|
+
user: {
|
|
40
|
+
id: string;
|
|
41
|
+
username: string;
|
|
42
|
+
email: string;
|
|
43
|
+
} | null;
|
|
44
|
+
class: {
|
|
45
|
+
name: string;
|
|
46
|
+
id: string;
|
|
47
|
+
section: string;
|
|
48
|
+
} | null;
|
|
49
|
+
department: {
|
|
50
|
+
name: string;
|
|
51
|
+
id: string;
|
|
52
|
+
color: string | null;
|
|
53
|
+
} | null;
|
|
54
|
+
tag: {
|
|
55
|
+
name: string;
|
|
56
|
+
id: string;
|
|
57
|
+
color: string;
|
|
58
|
+
} | null;
|
|
59
|
+
} & {
|
|
60
|
+
level: import(".prisma/client").$Enums.PermissionLevel;
|
|
61
|
+
id: string;
|
|
62
|
+
createdAt: Date;
|
|
63
|
+
schoolId: string | null;
|
|
64
|
+
userId: string | null;
|
|
65
|
+
departmentId: string | null;
|
|
66
|
+
folderId: string;
|
|
67
|
+
principalType: import(".prisma/client").$Enums.PermissionPrincipalType;
|
|
68
|
+
tagId: string | null;
|
|
69
|
+
classId: string | null;
|
|
70
|
+
grantedById: string;
|
|
71
|
+
})[];
|
|
72
|
+
meta: object;
|
|
73
|
+
}>;
|
|
74
|
+
/** Create a new explicit grant on a folder. */
|
|
75
|
+
grant: import("@trpc/server").TRPCMutationProcedure<{
|
|
76
|
+
input: {
|
|
77
|
+
level: "READ" | "WRITE";
|
|
78
|
+
folderId: string;
|
|
79
|
+
principal: PermissionPrincipalInput;
|
|
80
|
+
};
|
|
81
|
+
output: {
|
|
82
|
+
level: import(".prisma/client").$Enums.PermissionLevel;
|
|
83
|
+
id: string;
|
|
84
|
+
createdAt: Date;
|
|
85
|
+
schoolId: string | null;
|
|
86
|
+
userId: string | null;
|
|
87
|
+
departmentId: string | null;
|
|
88
|
+
folderId: string;
|
|
89
|
+
principalType: import(".prisma/client").$Enums.PermissionPrincipalType;
|
|
90
|
+
tagId: string | null;
|
|
91
|
+
classId: string | null;
|
|
92
|
+
grantedById: string;
|
|
93
|
+
};
|
|
94
|
+
meta: object;
|
|
95
|
+
}>;
|
|
96
|
+
/** Remove an explicit grant. Allowed for the granter or anyone with WRITE on the folder. */
|
|
97
|
+
revoke: import("@trpc/server").TRPCMutationProcedure<{
|
|
98
|
+
input: {
|
|
99
|
+
permissionId: string;
|
|
100
|
+
};
|
|
101
|
+
output: {
|
|
102
|
+
success: boolean;
|
|
103
|
+
};
|
|
104
|
+
meta: object;
|
|
105
|
+
}>;
|
|
106
|
+
/** Drive-style "Shared with me" — top-most folders explicitly granted to the caller. */
|
|
107
|
+
listSharedWithMe: import("@trpc/server").TRPCQueryProcedure<{
|
|
108
|
+
input: void;
|
|
109
|
+
output: {
|
|
110
|
+
folders: {
|
|
111
|
+
id: string;
|
|
112
|
+
name: string;
|
|
113
|
+
color: string | null;
|
|
114
|
+
}[];
|
|
115
|
+
files: never[];
|
|
116
|
+
};
|
|
117
|
+
meta: object;
|
|
118
|
+
}>;
|
|
119
|
+
}>>;
|
|
120
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"/","sources":["routers/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAKL,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AAiBpC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;IAC5B,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAOpE,+CAA+C;;;;;;;;;;;;;;;;;;;;;;IAiB/C,4FAA4F;;;;;;;;;;IAO5F,wFAAwF;;;;;;;;;;;;;GAIxF,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Permissions router. Backs the "Share" dialog and the "Shared with me" view.
|
|
3
|
+
*
|
|
4
|
+
* Permission semantics live in `services/permissions.ts`; this router is just
|
|
5
|
+
* a thin Zod-validated tRPC surface over those helpers.
|
|
6
|
+
*
|
|
7
|
+
* v1 grants only on folders. Files inherit from their parent folder. Adding
|
|
8
|
+
* file-level grants later is a non-breaking, additive change.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
!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]="dccc1159-4761-5abc-bf19-947124f66887")}catch(e){}}();
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
|
|
14
|
+
import { grantPermission, listPermissions, listSharedWithMe, revokePermission, } from "../services/permissions.js";
|
|
15
|
+
const principalSchema = z.discriminatedUnion("kind", [
|
|
16
|
+
z.object({ kind: z.literal("USER"), userId: z.string() }),
|
|
17
|
+
z.object({ kind: z.literal("TAG"), tagId: z.string() }),
|
|
18
|
+
z.object({ kind: z.literal("CLASS"), classId: z.string() }),
|
|
19
|
+
z.object({ kind: z.literal("CLASS_TEACHERS"), classId: z.string() }),
|
|
20
|
+
z.object({ kind: z.literal("CLASS_STUDENTS"), classId: z.string() }),
|
|
21
|
+
z.object({ kind: z.literal("DEPARTMENT"), departmentId: z.string() }),
|
|
22
|
+
z.object({ kind: z.literal("SCHOOL"), schoolId: z.string() }),
|
|
23
|
+
]);
|
|
24
|
+
const levelSchema = z.enum(["READ", "WRITE"]);
|
|
25
|
+
export const permissionsRouter = createTRPCRouter({
|
|
26
|
+
/** List all explicit grants on a folder. Caller must have WRITE. */
|
|
27
|
+
list: protectedProcedure
|
|
28
|
+
.input(z.object({ folderId: z.string() }))
|
|
29
|
+
.query(({ ctx, input }) => listPermissions(ctx.user.id, input.folderId)),
|
|
30
|
+
/** Create a new explicit grant on a folder. */
|
|
31
|
+
grant: protectedProcedure
|
|
32
|
+
.input(z.object({
|
|
33
|
+
folderId: z.string(),
|
|
34
|
+
principal: principalSchema,
|
|
35
|
+
level: levelSchema,
|
|
36
|
+
}))
|
|
37
|
+
.mutation(({ ctx, input }) => grantPermission(ctx.user.id, {
|
|
38
|
+
folderId: input.folderId,
|
|
39
|
+
principal: input.principal,
|
|
40
|
+
level: input.level,
|
|
41
|
+
})),
|
|
42
|
+
/** Remove an explicit grant. Allowed for the granter or anyone with WRITE on the folder. */
|
|
43
|
+
revoke: protectedProcedure
|
|
44
|
+
.input(z.object({ permissionId: z.string() }))
|
|
45
|
+
.mutation(({ ctx, input }) => revokePermission(ctx.user.id, input.permissionId)),
|
|
46
|
+
/** Drive-style "Shared with me" — top-most folders explicitly granted to the caller. */
|
|
47
|
+
listSharedWithMe: protectedProcedure.query(({ ctx }) => listSharedWithMe(ctx.user.id)),
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=permissions.js.map
|
|
50
|
+
//# debugId=dccc1159-4761-5abc-bf19-947124f66887
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sources":["routers/permissions.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Permissions router. Backs the \"Share\" dialog and the \"Shared with me\" view.\n *\n * Permission semantics live in `services/permissions.ts`; this router is just\n * a thin Zod-validated tRPC surface over those helpers.\n *\n * v1 grants only on folders. Files inherit from their parent folder. Adding\n * file-level grants later is a non-breaking, additive change.\n */\nimport { z } from \"zod\";\nimport { createTRPCRouter, protectedProcedure } from \"../trpc.js\";\nimport {\n grantPermission,\n listPermissions,\n listSharedWithMe,\n revokePermission,\n type PermissionPrincipalInput,\n} from \"../services/permissions.js\";\n\nconst principalSchema: z.ZodType<PermissionPrincipalInput> = z.discriminatedUnion(\n \"kind\",\n [\n z.object({ kind: z.literal(\"USER\"), userId: z.string() }),\n z.object({ kind: z.literal(\"TAG\"), tagId: z.string() }),\n z.object({ kind: z.literal(\"CLASS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"CLASS_TEACHERS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"CLASS_STUDENTS\"), classId: z.string() }),\n z.object({ kind: z.literal(\"DEPARTMENT\"), departmentId: z.string() }),\n z.object({ kind: z.literal(\"SCHOOL\"), schoolId: z.string() }),\n ]\n);\n\nconst levelSchema = z.enum([\"READ\", \"WRITE\"]);\n\nexport const permissionsRouter = createTRPCRouter({\n /** List all explicit grants on a folder. Caller must have WRITE. */\n list: protectedProcedure\n .input(z.object({ folderId: z.string() }))\n .query(({ ctx, input }) =>\n listPermissions(ctx.user!.id, input.folderId)\n ),\n\n /** Create a new explicit grant on a folder. */\n grant: protectedProcedure\n .input(\n z.object({\n folderId: z.string(),\n principal: principalSchema,\n level: levelSchema,\n })\n )\n .mutation(({ ctx, input }) =>\n grantPermission(ctx.user!.id, {\n folderId: input.folderId,\n principal: input.principal,\n level: input.level,\n })\n ),\n\n /** Remove an explicit grant. Allowed for the granter or anyone with WRITE on the folder. */\n revoke: protectedProcedure\n .input(z.object({ permissionId: z.string() }))\n .mutation(({ ctx, input }) =>\n revokePermission(ctx.user!.id, input.permissionId)\n ),\n\n /** Drive-style \"Shared with me\" — top-most folders explicitly granted to the caller. */\n listSharedWithMe: protectedProcedure.query(({ ctx }) =>\n listSharedWithMe(ctx.user!.id)\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"dccc1159-4761-5abc-bf19-947124f66887"}
|
|
@@ -66,6 +66,51 @@ export declare const studentProgressRouter: import("@trpc/server").TRPCBuiltRout
|
|
|
66
66
|
};
|
|
67
67
|
meta: object;
|
|
68
68
|
}>;
|
|
69
|
+
getInsights: import("@trpc/server").TRPCQueryProcedure<{
|
|
70
|
+
input: {
|
|
71
|
+
[x: string]: unknown;
|
|
72
|
+
classId: string;
|
|
73
|
+
studentId: string;
|
|
74
|
+
};
|
|
75
|
+
output: {
|
|
76
|
+
summary: string;
|
|
77
|
+
strengths: {
|
|
78
|
+
label: string;
|
|
79
|
+
evidence: string;
|
|
80
|
+
}[];
|
|
81
|
+
growth: {
|
|
82
|
+
label: string;
|
|
83
|
+
evidence: string;
|
|
84
|
+
}[];
|
|
85
|
+
talkingPoints: string[];
|
|
86
|
+
};
|
|
87
|
+
meta: object;
|
|
88
|
+
}>;
|
|
89
|
+
getForecast: import("@trpc/server").TRPCQueryProcedure<{
|
|
90
|
+
input: {
|
|
91
|
+
[x: string]: unknown;
|
|
92
|
+
classId: string;
|
|
93
|
+
studentId: string;
|
|
94
|
+
};
|
|
95
|
+
output: {
|
|
96
|
+
reason: string;
|
|
97
|
+
forecastLow: number;
|
|
98
|
+
forecastHigh: number;
|
|
99
|
+
risk: "on_track" | "watch" | "at_risk";
|
|
100
|
+
};
|
|
101
|
+
meta: object;
|
|
102
|
+
}>;
|
|
103
|
+
getStudentFocus: import("@trpc/server").TRPCQueryProcedure<{
|
|
104
|
+
input: {
|
|
105
|
+
[x: string]: unknown;
|
|
106
|
+
classId: string;
|
|
107
|
+
studentId: string;
|
|
108
|
+
};
|
|
109
|
+
output: {
|
|
110
|
+
focusItems: string[];
|
|
111
|
+
};
|
|
112
|
+
meta: object;
|
|
113
|
+
}>;
|
|
69
114
|
getClassRecommendations: import("@trpc/server").TRPCQueryProcedure<{
|
|
70
115
|
input: {
|
|
71
116
|
[x: string]: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studentProgress.d.ts","sourceRoot":"/","sources":["routers/studentProgress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"studentProgress.d.ts","sourceRoot":"/","sources":["routers/studentProgress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAqBxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEhC,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
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]="cbf91727-f312-5859-b18c-b745b032a75e")}catch(e){}}();
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { createTRPCRouter, protectedClassMemberProcedure, protectedTeacherProcedure, } from "../trpc.js";
|
|
5
|
-
import { chatAboutStudentProgress, dismissStudentRecommendation, getClassProgressRecommendations, getStudentProgressRecommendations, } from "../services/studentProgress.js";
|
|
5
|
+
import { chatAboutStudentProgress, dismissStudentRecommendation, getClassProgressRecommendations, getStudentProgressFocus, getStudentProgressForecast, getStudentProgressInsights, getStudentProgressRecommendations, } from "../services/studentProgress.js";
|
|
6
6
|
const progressInputSchema = z.object({
|
|
7
7
|
classId: z.string(),
|
|
8
8
|
studentId: z.string(),
|
|
@@ -11,6 +11,15 @@ export const studentProgressRouter = createTRPCRouter({
|
|
|
11
11
|
getRecommendations: protectedClassMemberProcedure
|
|
12
12
|
.input(progressInputSchema)
|
|
13
13
|
.query(({ ctx, input }) => getStudentProgressRecommendations(ctx.user.id, input.classId, input.studentId)),
|
|
14
|
+
getInsights: protectedClassMemberProcedure
|
|
15
|
+
.input(progressInputSchema)
|
|
16
|
+
.query(({ ctx, input }) => getStudentProgressInsights(ctx.user.id, input.classId, input.studentId)),
|
|
17
|
+
getForecast: protectedClassMemberProcedure
|
|
18
|
+
.input(progressInputSchema)
|
|
19
|
+
.query(({ ctx, input }) => getStudentProgressForecast(ctx.user.id, input.classId, input.studentId)),
|
|
20
|
+
getStudentFocus: protectedClassMemberProcedure
|
|
21
|
+
.input(progressInputSchema)
|
|
22
|
+
.query(({ ctx, input }) => getStudentProgressFocus(ctx.user.id, input.classId, input.studentId)),
|
|
14
23
|
getClassRecommendations: protectedTeacherProcedure
|
|
15
24
|
.input(z.object({ classId: z.string() }))
|
|
16
25
|
.query(({ ctx, input }) => getClassProgressRecommendations(ctx.user.id, input.classId)),
|
|
@@ -40,4 +49,4 @@ export const studentProgressRouter = createTRPCRouter({
|
|
|
40
49
|
})),
|
|
41
50
|
});
|
|
42
51
|
//# sourceMappingURL=studentProgress.js.map
|
|
43
|
-
//# debugId=
|
|
52
|
+
//# debugId=cbf91727-f312-5859-b18c-b745b032a75e
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studentProgress.js","sources":["routers/studentProgress.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport {\n createTRPCRouter,\n protectedClassMemberProcedure,\n protectedTeacherProcedure,\n} from \"../trpc.js\";\nimport {\n chatAboutStudentProgress,\n dismissStudentRecommendation,\n getClassProgressRecommendations,\n getStudentProgressRecommendations,\n} from \"../services/studentProgress.js\";\n\nconst progressInputSchema = z.object({\n classId: z.string(),\n studentId: z.string(),\n});\n\nexport const studentProgressRouter = createTRPCRouter({\n getRecommendations: protectedClassMemberProcedure\n .input(progressInputSchema)\n .query(({ ctx, input }) =>\n getStudentProgressRecommendations(\n ctx.user!.id,\n input.classId,\n input.studentId,\n ),\n ),\n\n getClassRecommendations: protectedTeacherProcedure\n .input(z.object({ classId: z.string() }))\n .query(({ ctx, input }) =>\n getClassProgressRecommendations(ctx.user!.id, input.classId),\n ),\n\n dismissRecommendation: protectedTeacherProcedure\n .input(\n z.object({\n classId: z.string(),\n studentId: z.string(),\n submissionId: z.string(),\n }),\n )\n .mutation(({ ctx, input }) =>\n dismissStudentRecommendation(ctx.user!.id, input),\n ),\n\n chat: protectedClassMemberProcedure\n .input(\n progressInputSchema.extend({\n message: z.string().min(1).max(4000),\n history: z\n .array(\n z.object({\n role: z.enum([\"user\", \"assistant\"]),\n content: z.string().min(1).max(4000),\n }),\n )\n .max(8)\n .optional(),\n }),\n )\n .mutation(({ ctx, input }) =>\n chatAboutStudentProgress(ctx.user!.id, {\n classId: input.classId,\n studentId: input.studentId,\n message: input.message,\n history: input.history,\n }),\n ),\n});\n"],"names":[],"mappings":";;AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,6BAA6B,EAC7B,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,+BAA+B,EAC/B,iCAAiC,GAClC,MAAM,gCAAgC,CAAC;AAExC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,CAAC;IACpD,kBAAkB,EAAE,6BAA6B;SAC9C,KAAK,CAAC,mBAAmB,CAAC;SAC1B,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CACxB,iCAAiC,CAC/B,GAAG,CAAC,IAAK,CAAC,EAAE,EACZ,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,SAAS,CAChB,CACF;IAEH,uBAAuB,EAAE,yBAAyB;SAC/C,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;SACxC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CACxB,+BAA+B,CAAC,GAAG,CAAC,IAAK,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAC7D;IAEH,qBAAqB,EAAE,yBAAyB;SAC7C,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;KACzB,CAAC,CACH;SACA,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAC3B,4BAA4B,CAAC,GAAG,CAAC,IAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAClD;IAEH,IAAI,EAAE,6BAA6B;SAChC,KAAK,CACJ,mBAAmB,CAAC,MAAM,CAAC;QACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;QACpC,OAAO,EAAE,CAAC;aACP,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;YACP,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;SACrC,CAAC,CACH;aACA,GAAG,CAAC,CAAC,CAAC;aACN,QAAQ,EAAE;KACd,CAAC,CACH;SACA,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAC3B,wBAAwB,CAAC,GAAG,CAAC,IAAK,CAAC,EAAE,EAAE;QACrC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CACH;CACJ,CAAC,CAAC","debug_id":"
|
|
1
|
+
{"version":3,"file":"studentProgress.js","sources":["routers/studentProgress.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport {\n createTRPCRouter,\n protectedClassMemberProcedure,\n protectedTeacherProcedure,\n} from \"../trpc.js\";\nimport {\n chatAboutStudentProgress,\n dismissStudentRecommendation,\n getClassProgressRecommendations,\n getStudentProgressFocus,\n getStudentProgressForecast,\n getStudentProgressInsights,\n getStudentProgressRecommendations,\n} from \"../services/studentProgress.js\";\n\nconst progressInputSchema = z.object({\n classId: z.string(),\n studentId: z.string(),\n});\n\nexport const studentProgressRouter = createTRPCRouter({\n getRecommendations: protectedClassMemberProcedure\n .input(progressInputSchema)\n .query(({ ctx, input }) =>\n getStudentProgressRecommendations(\n ctx.user!.id,\n input.classId,\n input.studentId,\n ),\n ),\n\n getInsights: protectedClassMemberProcedure\n .input(progressInputSchema)\n .query(({ ctx, input }) =>\n getStudentProgressInsights(ctx.user!.id, input.classId, input.studentId),\n ),\n\n getForecast: protectedClassMemberProcedure\n .input(progressInputSchema)\n .query(({ ctx, input }) =>\n getStudentProgressForecast(ctx.user!.id, input.classId, input.studentId),\n ),\n\n getStudentFocus: protectedClassMemberProcedure\n .input(progressInputSchema)\n .query(({ ctx, input }) =>\n getStudentProgressFocus(ctx.user!.id, input.classId, input.studentId),\n ),\n\n getClassRecommendations: protectedTeacherProcedure\n .input(z.object({ classId: z.string() }))\n .query(({ ctx, input }) =>\n getClassProgressRecommendations(ctx.user!.id, input.classId),\n ),\n\n dismissRecommendation: protectedTeacherProcedure\n .input(\n z.object({\n classId: z.string(),\n studentId: z.string(),\n submissionId: z.string(),\n }),\n )\n .mutation(({ ctx, input }) =>\n dismissStudentRecommendation(ctx.user!.id, input),\n ),\n\n chat: protectedClassMemberProcedure\n .input(\n progressInputSchema.extend({\n message: z.string().min(1).max(4000),\n history: z\n .array(\n z.object({\n role: z.enum([\"user\", \"assistant\"]),\n content: z.string().min(1).max(4000),\n }),\n )\n .max(8)\n .optional(),\n }),\n )\n .mutation(({ ctx, input }) =>\n chatAboutStudentProgress(ctx.user!.id, {\n classId: input.classId,\n studentId: input.studentId,\n message: input.message,\n history: input.history,\n }),\n ),\n});\n"],"names":[],"mappings":"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","debug_id":"cbf91727-f312-5859-b18c-b745b032a75e"}
|
package/dist/routers/tag.d.ts
CHANGED
|
@@ -79,9 +79,9 @@ export declare const tagRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
79
79
|
}>;
|
|
80
80
|
attach: import("@trpc/server").TRPCMutationProcedure<{
|
|
81
81
|
input: {
|
|
82
|
-
target: "CLASS" | "USER" | "RUBRIC" | "BOUNDARY";
|
|
83
|
-
targetId: string;
|
|
84
82
|
tagId: string;
|
|
83
|
+
target: "USER" | "CLASS" | "RUBRIC" | "BOUNDARY";
|
|
84
|
+
targetId: string;
|
|
85
85
|
};
|
|
86
86
|
output: {
|
|
87
87
|
id: string;
|
|
@@ -90,9 +90,9 @@ export declare const tagRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
90
90
|
}>;
|
|
91
91
|
detach: import("@trpc/server").TRPCMutationProcedure<{
|
|
92
92
|
input: {
|
|
93
|
-
target: "CLASS" | "USER" | "RUBRIC" | "BOUNDARY";
|
|
94
|
-
targetId: string;
|
|
95
93
|
tagId: string;
|
|
94
|
+
target: "USER" | "CLASS" | "RUBRIC" | "BOUNDARY";
|
|
95
|
+
targetId: string;
|
|
96
96
|
};
|
|
97
97
|
output: {
|
|
98
98
|
id: string;
|
|
@@ -101,7 +101,7 @@ export declare const tagRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
101
101
|
}>;
|
|
102
102
|
getAttached: import("@trpc/server").TRPCQueryProcedure<{
|
|
103
103
|
input: {
|
|
104
|
-
target: "
|
|
104
|
+
target: "USER" | "CLASS" | "RUBRIC" | "BOUNDARY";
|
|
105
105
|
targetId: string;
|
|
106
106
|
};
|
|
107
107
|
output: {
|
|
@@ -16,8 +16,8 @@ export declare function getAgenda(userId: string, weekStart: string): Promise<{
|
|
|
16
16
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
17
17
|
id: string;
|
|
18
18
|
createdAt: Date | null;
|
|
19
|
-
modifiedAt: Date | null;
|
|
20
19
|
classId: string;
|
|
20
|
+
modifiedAt: Date | null;
|
|
21
21
|
title: string;
|
|
22
22
|
instructions: string;
|
|
23
23
|
dueDate: Date;
|
|
@@ -64,8 +64,8 @@ export declare function getAgenda(userId: string, weekStart: string): Promise<{
|
|
|
64
64
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
65
65
|
id: string;
|
|
66
66
|
createdAt: Date | null;
|
|
67
|
-
modifiedAt: Date | null;
|
|
68
67
|
classId: string;
|
|
68
|
+
modifiedAt: Date | null;
|
|
69
69
|
title: string;
|
|
70
70
|
instructions: string;
|
|
71
71
|
dueDate: Date;
|