@goscribe/server 1.0.7 → 1.0.8

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.
@@ -11,7 +11,7 @@ const ArtifactType = {
11
11
  };
12
12
  export const flashcards = router({
13
13
  listSets: authedProcedure
14
- .input(z.object({ workspaceId: z.string().uuid() }))
14
+ .input(z.object({ workspaceId: z.string() }))
15
15
  .query(async ({ ctx, input }) => {
16
16
  const workspace = await ctx.db.workspace.findFirst({
17
17
  where: { id: input.workspaceId, ownerId: ctx.session.user.id },
@@ -20,44 +20,32 @@ export const flashcards = router({
20
20
  throw new TRPCError({ code: 'NOT_FOUND' });
21
21
  return ctx.db.artifact.findMany({
22
22
  where: { workspaceId: input.workspaceId, type: ArtifactType.FLASHCARD_SET },
23
- orderBy: { updatedAt: 'desc' },
24
- });
25
- }),
26
- createSet: authedProcedure
27
- .input(z.object({ workspaceId: z.string().uuid(), title: z.string().min(1).max(120) }))
28
- .mutation(async ({ ctx, input }) => {
29
- const workspace = await ctx.db.workspace.findFirst({
30
- where: { id: input.workspaceId, ownerId: ctx.session.user.id },
31
- });
32
- if (!workspace)
33
- throw new TRPCError({ code: 'NOT_FOUND' });
34
- return ctx.db.artifact.create({
35
- data: {
36
- workspaceId: input.workspaceId,
37
- type: ArtifactType.FLASHCARD_SET,
38
- title: input.title,
39
- createdById: ctx.session.user.id,
23
+ include: {
24
+ versions: {
25
+ orderBy: { version: 'desc' },
26
+ take: 1, // Get only the latest version
27
+ },
40
28
  },
29
+ orderBy: { updatedAt: 'desc' },
41
30
  });
42
31
  }),
43
- getSet: authedProcedure
44
- .input(z.object({ setId: z.string().uuid() }))
32
+ listCards: authedProcedure
33
+ .input(z.object({ workspaceId: z.string() }))
45
34
  .query(async ({ ctx, input }) => {
46
35
  const set = await ctx.db.artifact.findFirst({
47
- where: {
48
- id: input.setId,
49
- type: ArtifactType.FLASHCARD_SET,
50
- workspace: { ownerId: ctx.session.user.id },
36
+ where: { workspaceId: input.workspaceId, type: ArtifactType.FLASHCARD_SET, workspace: { ownerId: ctx.session.user.id } },
37
+ include: {
38
+ flashcards: true,
51
39
  },
52
- include: { flashcards: true },
40
+ orderBy: { updatedAt: 'desc' },
53
41
  });
54
42
  if (!set)
55
43
  throw new TRPCError({ code: 'NOT_FOUND' });
56
- return set;
44
+ return set.flashcards;
57
45
  }),
58
46
  createCard: authedProcedure
59
47
  .input(z.object({
60
- setId: z.string().uuid(),
48
+ workspaceId: z.string(),
61
49
  front: z.string().min(1),
62
50
  back: z.string().min(1),
63
51
  tags: z.array(z.string()).optional(),
@@ -65,13 +53,19 @@ export const flashcards = router({
65
53
  }))
66
54
  .mutation(async ({ ctx, input }) => {
67
55
  const set = await ctx.db.artifact.findFirst({
68
- where: { id: input.setId, type: ArtifactType.FLASHCARD_SET, workspace: { ownerId: ctx.session.user.id } },
56
+ where: { type: ArtifactType.FLASHCARD_SET, workspace: {
57
+ id: input.workspaceId,
58
+ } },
59
+ include: {
60
+ flashcards: true,
61
+ },
62
+ orderBy: { updatedAt: 'desc' },
69
63
  });
70
64
  if (!set)
71
65
  throw new TRPCError({ code: 'NOT_FOUND' });
72
66
  return ctx.db.flashcard.create({
73
67
  data: {
74
- artifactId: input.setId,
68
+ artifactId: set.id,
75
69
  front: input.front,
76
70
  back: input.back,
77
71
  tags: input.tags ?? [],
@@ -81,7 +75,7 @@ export const flashcards = router({
81
75
  }),
82
76
  updateCard: authedProcedure
83
77
  .input(z.object({
84
- cardId: z.string().uuid(),
78
+ cardId: z.string(),
85
79
  front: z.string().optional(),
86
80
  back: z.string().optional(),
87
81
  tags: z.array(z.string()).optional(),
@@ -104,7 +98,7 @@ export const flashcards = router({
104
98
  });
105
99
  }),
106
100
  deleteCard: authedProcedure
107
- .input(z.object({ cardId: z.string().uuid() }))
101
+ .input(z.object({ cardId: z.string() }))
108
102
  .mutation(async ({ ctx, input }) => {
109
103
  const card = await ctx.db.flashcard.findFirst({
110
104
  where: { id: input.cardId, artifact: { workspace: { ownerId: ctx.session.user.id } } },
@@ -114,14 +108,4 @@ export const flashcards = router({
114
108
  await ctx.db.flashcard.delete({ where: { id: input.cardId } });
115
109
  return true;
116
110
  }),
117
- deleteSet: authedProcedure
118
- .input(z.object({ setId: z.string().uuid() }))
119
- .mutation(async ({ ctx, input }) => {
120
- const deleted = await ctx.db.artifact.deleteMany({
121
- where: { id: input.setId, type: ArtifactType.FLASHCARD_SET, workspace: { ownerId: ctx.session.user.id } },
122
- });
123
- if (deleted.count === 0)
124
- throw new TRPCError({ code: 'NOT_FOUND' });
125
- return true;
126
- }),
127
111
  });
@@ -4,17 +4,37 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
4
4
  session: any;
5
5
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
6
  res: import("express").Response<any, Record<string, any>>;
7
- cookies: any;
7
+ cookies: Record<string, string | undefined>;
8
8
  };
9
9
  meta: object;
10
10
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
11
11
  transformer: true;
12
12
  }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
13
- listSets: import("@trpc/server").TRPCQueryProcedure<{
13
+ list: import("@trpc/server").TRPCQueryProcedure<{
14
14
  input: {
15
15
  workspaceId: string;
16
16
  };
17
- output: {
17
+ output: ({
18
+ versions: {
19
+ id: string;
20
+ createdAt: Date;
21
+ createdById: string | null;
22
+ artifactId: string;
23
+ content: string;
24
+ data: import("@prisma/client/runtime/library").JsonValue | null;
25
+ version: number;
26
+ }[];
27
+ questions: {
28
+ meta: import("@prisma/client/runtime/library").JsonValue | null;
29
+ id: string;
30
+ createdAt: Date;
31
+ artifactId: string;
32
+ order: number;
33
+ prompt: string;
34
+ answer: string | null;
35
+ difficulty: import("@prisma/client").$Enums.Difficulty;
36
+ }[];
37
+ } & {
18
38
  id: string;
19
39
  createdAt: Date;
20
40
  updatedAt: Date;
@@ -23,10 +43,10 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
23
43
  type: import("@prisma/client").$Enums.ArtifactType;
24
44
  isArchived: boolean;
25
45
  createdById: string | null;
26
- }[];
46
+ })[];
27
47
  meta: object;
28
48
  }>;
29
- createSet: import("@trpc/server").TRPCMutationProcedure<{
49
+ createWorksheet: import("@trpc/server").TRPCMutationProcedure<{
30
50
  input: {
31
51
  workspaceId: string;
32
52
  title: string;
@@ -43,9 +63,9 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
43
63
  };
44
64
  meta: object;
45
65
  }>;
46
- getSet: import("@trpc/server").TRPCQueryProcedure<{
66
+ get: import("@trpc/server").TRPCQueryProcedure<{
47
67
  input: {
48
- setId: string;
68
+ worksheetId: string;
49
69
  };
50
70
  output: {
51
71
  questions: {
@@ -70,9 +90,9 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
70
90
  };
71
91
  meta: object;
72
92
  }>;
73
- createQuestion: import("@trpc/server").TRPCMutationProcedure<{
93
+ createWorksheetQuestion: import("@trpc/server").TRPCMutationProcedure<{
74
94
  input: {
75
- setId: string;
95
+ worksheetId: string;
76
96
  prompt: string;
77
97
  answer?: string | undefined;
78
98
  difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
@@ -91,9 +111,9 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
91
111
  };
92
112
  meta: object;
93
113
  }>;
94
- updateQuestion: import("@trpc/server").TRPCMutationProcedure<{
114
+ updateWorksheetQuestion: import("@trpc/server").TRPCMutationProcedure<{
95
115
  input: {
96
- questionId: string;
116
+ worksheetQuestionId: string;
97
117
  prompt?: string | undefined;
98
118
  answer?: string | undefined;
99
119
  difficulty?: "EASY" | "MEDIUM" | "HARD" | undefined;
@@ -112,16 +132,16 @@ export declare const worksheets: import("@trpc/server").TRPCBuiltRouter<{
112
132
  };
113
133
  meta: object;
114
134
  }>;
115
- deleteQuestion: import("@trpc/server").TRPCMutationProcedure<{
135
+ deleteWorksheetQuestion: import("@trpc/server").TRPCMutationProcedure<{
116
136
  input: {
117
- questionId: string;
137
+ worksheetQuestionId: string;
118
138
  };
119
139
  output: boolean;
120
140
  meta: object;
121
141
  }>;
122
- deleteSet: import("@trpc/server").TRPCMutationProcedure<{
142
+ deleteWorksheet: import("@trpc/server").TRPCMutationProcedure<{
123
143
  input: {
124
- setId: string;
144
+ worksheetId: string;
125
145
  };
126
146
  output: boolean;
127
147
  meta: object;
@@ -12,22 +12,27 @@ const Difficulty = {
12
12
  };
13
13
  export const worksheets = router({
14
14
  // List all worksheet artifacts for a workspace
15
- listSets: authedProcedure
16
- .input(z.object({ workspaceId: z.string().uuid() }))
15
+ list: authedProcedure
16
+ .input(z.object({ workspaceId: z.string() }))
17
17
  .query(async ({ ctx, input }) => {
18
- const workspace = await ctx.db.workspace.findFirst({
19
- where: { id: input.workspaceId, ownerId: ctx.session.user.id },
20
- });
21
- if (!workspace)
22
- throw new TRPCError({ code: 'NOT_FOUND' });
23
- return ctx.db.artifact.findMany({
18
+ const worksheets = await ctx.db.artifact.findMany({
24
19
  where: { workspaceId: input.workspaceId, type: ArtifactType.WORKSHEET },
20
+ include: {
21
+ versions: {
22
+ orderBy: { version: 'desc' },
23
+ take: 1, // Get only the latest version
24
+ },
25
+ questions: true,
26
+ },
25
27
  orderBy: { updatedAt: 'desc' },
26
28
  });
29
+ if (!worksheets)
30
+ throw new TRPCError({ code: 'NOT_FOUND' });
31
+ return worksheets;
27
32
  }),
28
33
  // Create a worksheet set
29
- createSet: authedProcedure
30
- .input(z.object({ workspaceId: z.string().uuid(), title: z.string().min(1).max(120) }))
34
+ createWorksheet: authedProcedure
35
+ .input(z.object({ workspaceId: z.string(), title: z.string().min(1).max(120) }))
31
36
  .mutation(async ({ ctx, input }) => {
32
37
  const workspace = await ctx.db.workspace.findFirst({
33
38
  where: { id: input.workspaceId, ownerId: ctx.session.user.id },
@@ -44,25 +49,25 @@ export const worksheets = router({
44
49
  });
45
50
  }),
46
51
  // Get a worksheet with its questions
47
- getSet: authedProcedure
48
- .input(z.object({ setId: z.string().uuid() }))
52
+ get: authedProcedure
53
+ .input(z.object({ worksheetId: z.string() }))
49
54
  .query(async ({ ctx, input }) => {
50
- const set = await ctx.db.artifact.findFirst({
55
+ const worksheet = await ctx.db.artifact.findFirst({
51
56
  where: {
52
- id: input.setId,
57
+ id: input.worksheetId,
53
58
  type: ArtifactType.WORKSHEET,
54
59
  workspace: { ownerId: ctx.session.user.id },
55
60
  },
56
61
  include: { questions: true },
57
62
  });
58
- if (!set)
63
+ if (!worksheet)
59
64
  throw new TRPCError({ code: 'NOT_FOUND' });
60
- return set;
65
+ return worksheet;
61
66
  }),
62
67
  // Add a question to a worksheet
63
- createQuestion: authedProcedure
68
+ createWorksheetQuestion: authedProcedure
64
69
  .input(z.object({
65
- setId: z.string().uuid(),
70
+ worksheetId: z.string(),
66
71
  prompt: z.string().min(1),
67
72
  answer: z.string().optional(),
68
73
  difficulty: z.enum(['EASY', 'MEDIUM', 'HARD']).optional(),
@@ -70,14 +75,14 @@ export const worksheets = router({
70
75
  meta: z.record(z.string(), z.unknown()).optional(),
71
76
  }))
72
77
  .mutation(async ({ ctx, input }) => {
73
- const set = await ctx.db.artifact.findFirst({
74
- where: { id: input.setId, type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } },
78
+ const worksheet = await ctx.db.artifact.findFirst({
79
+ where: { id: input.worksheetId, type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } },
75
80
  });
76
- if (!set)
81
+ if (!worksheet)
77
82
  throw new TRPCError({ code: 'NOT_FOUND' });
78
83
  return ctx.db.worksheetQuestion.create({
79
84
  data: {
80
- artifactId: input.setId,
85
+ artifactId: input.worksheetId,
81
86
  prompt: input.prompt,
82
87
  answer: input.answer,
83
88
  difficulty: (input.difficulty ?? Difficulty.MEDIUM),
@@ -87,9 +92,9 @@ export const worksheets = router({
87
92
  });
88
93
  }),
89
94
  // Update a question
90
- updateQuestion: authedProcedure
95
+ updateWorksheetQuestion: authedProcedure
91
96
  .input(z.object({
92
- questionId: z.string().uuid(),
97
+ worksheetQuestionId: z.string(),
93
98
  prompt: z.string().optional(),
94
99
  answer: z.string().optional(),
95
100
  difficulty: z.enum(['EASY', 'MEDIUM', 'HARD']).optional(),
@@ -98,12 +103,12 @@ export const worksheets = router({
98
103
  }))
99
104
  .mutation(async ({ ctx, input }) => {
100
105
  const q = await ctx.db.worksheetQuestion.findFirst({
101
- where: { id: input.questionId, artifact: { type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } } },
106
+ where: { id: input.worksheetQuestionId, artifact: { type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } } },
102
107
  });
103
108
  if (!q)
104
109
  throw new TRPCError({ code: 'NOT_FOUND' });
105
110
  return ctx.db.worksheetQuestion.update({
106
- where: { id: input.questionId },
111
+ where: { id: input.worksheetQuestionId },
107
112
  data: {
108
113
  prompt: input.prompt ?? q.prompt,
109
114
  answer: input.answer ?? q.answer,
@@ -114,23 +119,23 @@ export const worksheets = router({
114
119
  });
115
120
  }),
116
121
  // Delete a question
117
- deleteQuestion: authedProcedure
118
- .input(z.object({ questionId: z.string().uuid() }))
122
+ deleteWorksheetQuestion: authedProcedure
123
+ .input(z.object({ worksheetQuestionId: z.string() }))
119
124
  .mutation(async ({ ctx, input }) => {
120
125
  const q = await ctx.db.worksheetQuestion.findFirst({
121
- where: { id: input.questionId, artifact: { workspace: { ownerId: ctx.session.user.id } } },
126
+ where: { id: input.worksheetQuestionId, artifact: { workspace: { ownerId: ctx.session.user.id } } },
122
127
  });
123
128
  if (!q)
124
129
  throw new TRPCError({ code: 'NOT_FOUND' });
125
- await ctx.db.worksheetQuestion.delete({ where: { id: input.questionId } });
130
+ await ctx.db.worksheetQuestion.delete({ where: { id: input.worksheetQuestionId } });
126
131
  return true;
127
132
  }),
128
133
  // Delete a worksheet set and its questions
129
- deleteSet: authedProcedure
130
- .input(z.object({ setId: z.string().uuid() }))
134
+ deleteWorksheet: authedProcedure
135
+ .input(z.object({ worksheetId: z.string() }))
131
136
  .mutation(async ({ ctx, input }) => {
132
137
  const deleted = await ctx.db.artifact.deleteMany({
133
- where: { id: input.setId, type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } },
138
+ where: { id: input.worksheetId, type: ArtifactType.WORKSHEET, workspace: { ownerId: ctx.session.user.id } },
134
139
  });
135
140
  if (deleted.count === 0)
136
141
  throw new TRPCError({ code: 'NOT_FOUND' });
@@ -4,7 +4,7 @@ export declare const workspace: import("@trpc/server").TRPCBuiltRouter<{
4
4
  session: any;
5
5
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
6
  res: import("express").Response<any, Record<string, any>>;
7
- cookies: any;
7
+ cookies: Record<string, string | undefined>;
8
8
  };
9
9
  meta: object;
10
10
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  import { TRPCError } from '@trpc/server';
3
3
  import { router, authedProcedure } from '../trpc.js';
4
4
  import { bucket } from '../lib/storage.js';
5
+ import { ArtifactType } from '@prisma/client';
5
6
  export const workspace = router({
6
7
  // List current user's workspaces
7
8
  list: authedProcedure
@@ -25,6 +26,18 @@ export const workspace = router({
25
26
  title: input.name,
26
27
  description: input.description,
27
28
  ownerId: ctx.session.user.id,
29
+ artifacts: {
30
+ create: {
31
+ type: ArtifactType.FLASHCARD_SET,
32
+ title: "New Flashcard Set",
33
+ },
34
+ createMany: {
35
+ data: [
36
+ { type: ArtifactType.WORKSHEET, title: "Worksheet 1" },
37
+ { type: ArtifactType.WORKSHEET, title: "Worksheet 2" },
38
+ ],
39
+ },
40
+ },
28
41
  },
29
42
  });
30
43
  return ws;
package/dist/server.d.ts CHANGED
@@ -1 +1 @@
1
- export {};
1
+ import 'dotenv/config';
package/dist/server.js CHANGED
@@ -1,3 +1,4 @@
1
+ import 'dotenv/config';
1
2
  import express from 'express';
2
3
  import cors from 'cors';
3
4
  import helmet from 'helmet';
package/dist/trpc.d.ts CHANGED
@@ -4,7 +4,7 @@ export declare const router: import("@trpc/server").TRPCRouterBuilder<{
4
4
  session: any;
5
5
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
6
6
  res: import("express").Response<any, Record<string, any>>;
7
- cookies: any;
7
+ cookies: Record<string, string | undefined>;
8
8
  };
9
9
  meta: object;
10
10
  errorShape: import("@trpc/server").TRPCDefaultErrorShape;
@@ -15,20 +15,20 @@ export declare const middleware: <$ContextOverrides>(fn: import("@trpc/server").
15
15
  session: any;
16
16
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
17
17
  res: import("express").Response<any, Record<string, any>>;
18
- cookies: any;
18
+ cookies: Record<string, string | undefined>;
19
19
  }, object, object, $ContextOverrides, unknown>) => import("@trpc/server").TRPCMiddlewareBuilder<{
20
20
  db: import("@prisma/client").PrismaClient<import("@prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>;
21
21
  session: any;
22
22
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
23
23
  res: import("express").Response<any, Record<string, any>>;
24
- cookies: any;
24
+ cookies: Record<string, string | undefined>;
25
25
  }, object, $ContextOverrides, unknown>;
26
26
  export declare const publicProcedure: import("@trpc/server").TRPCProcedureBuilder<{
27
27
  db: import("@prisma/client").PrismaClient<import("@prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>;
28
28
  session: any;
29
29
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
30
30
  res: import("express").Response<any, Record<string, any>>;
31
- cookies: any;
31
+ cookies: Record<string, string | undefined>;
32
32
  }, object, object, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, false>;
33
33
  /** Exported authed procedure */
34
34
  export declare const authedProcedure: import("@trpc/server").TRPCProcedureBuilder<{
@@ -36,7 +36,7 @@ export declare const authedProcedure: import("@trpc/server").TRPCProcedureBuilde
36
36
  session: any;
37
37
  req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
38
38
  res: import("express").Response<any, Record<string, any>>;
39
- cookies: any;
39
+ cookies: Record<string, string | undefined>;
40
40
  }, object, {
41
41
  session: any;
42
42
  }, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, import("@trpc/server").TRPCUnsetMarker, false>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goscribe/server",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,6 +22,7 @@
22
22
  "@auth/express": "^0.11.0",
23
23
  "@auth/prisma-adapter": "^2.10.0",
24
24
  "@google-cloud/storage": "^7.17.0",
25
+ "@goscribe/server": "^1.0.7",
25
26
  "@prisma/client": "^6.14.0",
26
27
  "@trpc/server": "^11.5.0",
27
28
  "bcryptjs": "^3.0.2",
package/src/lib/auth.ts CHANGED
@@ -7,7 +7,7 @@ export function verifyCustomAuthCookie(cookieValue: string | undefined): { userI
7
7
  return null;
8
8
  }
9
9
 
10
- const secret = process.env.CUSTOM_AUTH_SECRET;
10
+ const secret = process.env.AUTH_SECRET;
11
11
 
12
12
  if (!secret) {
13
13
  return null;
@@ -12,7 +12,7 @@ const ArtifactType = {
12
12
 
13
13
  export const flashcards = router({
14
14
  listSets: authedProcedure
15
- .input(z.object({ workspaceId: z.string().uuid() }))
15
+ .input(z.object({ workspaceId: z.string() }))
16
16
  .query(async ({ ctx, input }) => {
17
17
  const workspace = await ctx.db.workspace.findFirst({
18
18
  where: { id: input.workspaceId, ownerId: ctx.session.user.id },
@@ -29,42 +29,22 @@ export const flashcards = router({
29
29
  orderBy: { updatedAt: 'desc' },
30
30
  });
31
31
  }),
32
-
33
- createSet: authedProcedure
34
- .input(z.object({ workspaceId: z.string().uuid(), title: z.string().min(1).max(120) }))
35
- .mutation(async ({ ctx, input }) => {
36
- const workspace = await ctx.db.workspace.findFirst({
37
- where: { id: input.workspaceId, ownerId: ctx.session.user.id },
38
- });
39
- if (!workspace) throw new TRPCError({ code: 'NOT_FOUND' });
40
- return ctx.db.artifact.create({
41
- data: {
42
- workspaceId: input.workspaceId,
43
- type: ArtifactType.FLASHCARD_SET,
44
- title: input.title,
45
- createdById: ctx.session.user.id,
46
- },
47
- });
48
- }),
49
-
50
- getSet: authedProcedure
51
- .input(z.object({ setId: z.string().uuid() }))
32
+ listCards: authedProcedure
33
+ .input(z.object({ workspaceId: z.string() }))
52
34
  .query(async ({ ctx, input }) => {
53
35
  const set = await ctx.db.artifact.findFirst({
54
- where: {
55
- id: input.setId,
56
- type: ArtifactType.FLASHCARD_SET,
57
- workspace: { ownerId: ctx.session.user.id },
36
+ where: { workspaceId: input.workspaceId, type: ArtifactType.FLASHCARD_SET, workspace: { ownerId: ctx.session.user.id } },
37
+ include: {
38
+ flashcards: true,
58
39
  },
59
- include: { flashcards: true },
40
+ orderBy: { updatedAt: 'desc' },
60
41
  });
61
42
  if (!set) throw new TRPCError({ code: 'NOT_FOUND' });
62
- return set;
43
+ return set.flashcards;
63
44
  }),
64
-
65
45
  createCard: authedProcedure
66
46
  .input(z.object({
67
- setId: z.string().uuid(),
47
+ workspaceId: z.string(),
68
48
  front: z.string().min(1),
69
49
  back: z.string().min(1),
70
50
  tags: z.array(z.string()).optional(),
@@ -72,12 +52,18 @@ export const flashcards = router({
72
52
  }))
73
53
  .mutation(async ({ ctx, input }) => {
74
54
  const set = await ctx.db.artifact.findFirst({
75
- where: { id: input.setId, type: ArtifactType.FLASHCARD_SET, workspace: { ownerId: ctx.session.user.id } },
55
+ where: { type: ArtifactType.FLASHCARD_SET, workspace: {
56
+ id: input.workspaceId,
57
+ } },
58
+ include: {
59
+ flashcards: true,
60
+ },
61
+ orderBy: { updatedAt: 'desc' },
76
62
  });
77
63
  if (!set) throw new TRPCError({ code: 'NOT_FOUND' });
78
64
  return ctx.db.flashcard.create({
79
65
  data: {
80
- artifactId: input.setId,
66
+ artifactId: set.id,
81
67
  front: input.front,
82
68
  back: input.back,
83
69
  tags: input.tags ?? [],
@@ -88,7 +74,7 @@ export const flashcards = router({
88
74
 
89
75
  updateCard: authedProcedure
90
76
  .input(z.object({
91
- cardId: z.string().uuid(),
77
+ cardId: z.string(),
92
78
  front: z.string().optional(),
93
79
  back: z.string().optional(),
94
80
  tags: z.array(z.string()).optional(),
@@ -111,7 +97,7 @@ export const flashcards = router({
111
97
  }),
112
98
 
113
99
  deleteCard: authedProcedure
114
- .input(z.object({ cardId: z.string().uuid() }))
100
+ .input(z.object({ cardId: z.string() }))
115
101
  .mutation(async ({ ctx, input }) => {
116
102
  const card = await ctx.db.flashcard.findFirst({
117
103
  where: { id: input.cardId, artifact: { workspace: { ownerId: ctx.session.user.id } } },
@@ -120,16 +106,6 @@ export const flashcards = router({
120
106
  await ctx.db.flashcard.delete({ where: { id: input.cardId } });
121
107
  return true;
122
108
  }),
123
-
124
- deleteSet: authedProcedure
125
- .input(z.object({ setId: z.string().uuid() }))
126
- .mutation(async ({ ctx, input }) => {
127
- const deleted = await ctx.db.artifact.deleteMany({
128
- where: { id: input.setId, type: ArtifactType.FLASHCARD_SET, workspace: { ownerId: ctx.session.user.id } },
129
- });
130
- if (deleted.count === 0) throw new TRPCError({ code: 'NOT_FOUND' });
131
- return true;
132
- }),
133
109
  });
134
110
 
135
111