@goscribe/server 1.1.7 → 1.3.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.
Files changed (56) hide show
  1. package/.env.example +43 -0
  2. package/check-difficulty.cjs +14 -0
  3. package/check-questions.cjs +14 -0
  4. package/db-summary.cjs +22 -0
  5. package/dist/routers/auth.js +1 -1
  6. package/mcq-test.cjs +36 -0
  7. package/package.json +10 -2
  8. package/prisma/migrations/20260413143206_init/migration.sql +873 -0
  9. package/prisma/schema.prisma +485 -292
  10. package/src/context.ts +4 -1
  11. package/src/lib/activity_human_description.test.ts +28 -0
  12. package/src/lib/activity_human_description.ts +239 -0
  13. package/src/lib/activity_log_service.test.ts +37 -0
  14. package/src/lib/activity_log_service.ts +353 -0
  15. package/src/lib/ai-session.ts +194 -112
  16. package/src/lib/constants.ts +14 -0
  17. package/src/lib/email.ts +230 -0
  18. package/src/lib/env.ts +23 -6
  19. package/src/lib/inference.ts +3 -3
  20. package/src/lib/logger.ts +26 -9
  21. package/src/lib/notification-service.test.ts +106 -0
  22. package/src/lib/notification-service.ts +677 -0
  23. package/src/lib/prisma.ts +6 -1
  24. package/src/lib/pusher.ts +90 -6
  25. package/src/lib/retry.ts +61 -0
  26. package/src/lib/storage.ts +2 -2
  27. package/src/lib/stripe.ts +39 -0
  28. package/src/lib/subscription_service.ts +722 -0
  29. package/src/lib/usage_service.ts +74 -0
  30. package/src/lib/worksheet-generation.test.ts +31 -0
  31. package/src/lib/worksheet-generation.ts +139 -0
  32. package/src/lib/workspace-access.ts +13 -0
  33. package/src/routers/_app.ts +11 -0
  34. package/src/routers/admin.ts +710 -0
  35. package/src/routers/annotations.ts +227 -0
  36. package/src/routers/auth.ts +432 -33
  37. package/src/routers/copilot.ts +719 -0
  38. package/src/routers/flashcards.ts +207 -80
  39. package/src/routers/members.ts +280 -80
  40. package/src/routers/notifications.ts +142 -0
  41. package/src/routers/payment.ts +448 -0
  42. package/src/routers/podcast.ts +133 -108
  43. package/src/routers/studyguide.ts +80 -74
  44. package/src/routers/worksheets.ts +300 -80
  45. package/src/routers/workspace.ts +538 -328
  46. package/src/scripts/purge-deleted-users.ts +167 -0
  47. package/src/server.ts +140 -12
  48. package/src/services/flashcard-progress.service.ts +52 -43
  49. package/src/trpc.ts +184 -5
  50. package/test-generate.js +30 -0
  51. package/test-ratio.cjs +9 -0
  52. package/zod-test.cjs +22 -0
  53. package/prisma/migrations/20250826124819_add_worksheet_difficulty_and_estimated_time/migration.sql +0 -213
  54. package/prisma/migrations/20250826133236_add_worksheet_question_progress/migration.sql +0 -31
  55. package/prisma/seed.mjs +0 -135
  56. package/src/routers/meetingsummary.ts +0 -416
package/.env.example ADDED
@@ -0,0 +1,43 @@
1
+ # ──────────────────────────────────────────────
2
+ # Scribe Server Environment Variables
3
+ # Copy this file to .env and fill in your values
4
+ # ──────────────────────────────────────────────
5
+
6
+ # Auth
7
+ AUTH_SECRET="your-auth-secret-here"
8
+ AUTH_TRUST_HOST=true
9
+ AUTH_URL=http://localhost:3001
10
+
11
+ # Database (PostgreSQL via Supabase)
12
+ DATABASE_URL="postgresql://user:password@host:6543/postgres?pgbouncer=true"
13
+ DIRECT_URL="postgresql://user:password@host:5432/postgres"
14
+
15
+ # AI Inference
16
+ DONT_TEST_INFERENCE=false
17
+ INFERENCE_API_URL=http://localhost:5000
18
+ INFERENCE_API_KEY=your-inference-api-key
19
+ INFERENCE_BASE_URL=https://api.cohere.ai/compatibility/v1
20
+
21
+ # Supabase Storage
22
+ SUPABASE_URL=https://your-project.supabase.co
23
+ SUPABASE_SERVICE_ROLE_KEY=your-supabase-service-role-key
24
+
25
+ # Google Cloud Storage (for podcast audio)
26
+ GCP_PROJECT_ID=your-gcp-project
27
+ GCP_BUCKET=your-bucket-name
28
+ GCP_CLIENT_EMAIL=your-service-account@your-project.iam.gserviceaccount.com
29
+ GCP_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nyour-private-key\n-----END PRIVATE KEY-----\n"
30
+
31
+ # Pusher (real-time events)
32
+ PUSHER_APP_ID=your-pusher-app-id
33
+ PUSHER_KEY=your-pusher-key
34
+ PUSHER_SECRET=your-pusher-secret
35
+ PUSHER_CLUSTER=your-cluster
36
+
37
+ # Email (Resend)
38
+ RESEND_API_KEY=re_your_resend_api_key
39
+ EMAIL_FROM=Scribe <noreply@yourdomain.com>
40
+
41
+ # Optional
42
+ COHERE_API_KEY=your-cohere-key
43
+ MURF_TTS_KEY=your-murf-tts-key
@@ -0,0 +1,14 @@
1
+ const { PrismaClient } = require('@prisma/client');
2
+ const prisma = new PrismaClient();
3
+
4
+ async function check() {
5
+ const artifacts = await prisma.artifact.findMany({
6
+ where: { type: 'WORKSHEET' },
7
+ orderBy: { createdAt: 'desc' },
8
+ take: 5,
9
+ select: { id: true, title: true, difficulty: true, generatingMetadata: true }
10
+ });
11
+ console.log("Recent Worksheets:", JSON.stringify(artifacts, null, 2));
12
+ }
13
+
14
+ check().catch(console.error).finally(() => prisma.$disconnect());
@@ -0,0 +1,14 @@
1
+ const { PrismaClient } = require('@prisma/client');
2
+ const prisma = new PrismaClient();
3
+
4
+ async function check() {
5
+ const artifacts = await prisma.artifact.findMany({
6
+ where: { type: 'WORKSHEET' },
7
+ orderBy: { createdAt: 'desc' },
8
+ take: 3,
9
+ select: { id: true, title: true, generatingMetadata: true, createdAt: true, questions: true }
10
+ });
11
+ console.log("Recent Worksheets:", JSON.stringify(artifacts, null, 2));
12
+ }
13
+
14
+ check().catch(console.error).finally(() => prisma.$disconnect());
package/db-summary.cjs ADDED
@@ -0,0 +1,22 @@
1
+ const { PrismaClient } = require('@prisma/client');
2
+ const prisma = new PrismaClient();
3
+
4
+ async function summary() {
5
+ const artifacts = await prisma.artifact.findMany({
6
+ where: { type: 'WORKSHEET' },
7
+ orderBy: { createdAt: 'desc' },
8
+ take: 10,
9
+ select: { id: true, createdAt: true, generatingMetadata: true, questions: { select: { type: true } } }
10
+ });
11
+
12
+ for (const a of artifacts) {
13
+ let mcqs = 0; let texts = 0;
14
+ for (const q of a.questions) {
15
+ if (q.type === 'MULTIPLE_CHOICE') mcqs++;
16
+ else if (q.type === 'TEXT') texts++;
17
+ }
18
+ console.log(`Worksheet ${a.id} at ${a.createdAt.toISOString()}: ${mcqs} MCQs, ${texts} Texts`);
19
+ }
20
+ }
21
+
22
+ summary().catch(console.error).finally(() => prisma.$disconnect());
@@ -4,7 +4,7 @@ import bcrypt from 'bcryptjs';
4
4
  import { serialize } from 'cookie';
5
5
  import crypto from 'node:crypto';
6
6
  import { TRPCError } from '@trpc/server';
7
- import { supabaseClient } from 'src/lib/storage.js';
7
+ import { supabaseClient } from '../lib/storage.js';
8
8
  // Helper to create custom auth token
9
9
  function createCustomAuthToken(userId) {
10
10
  const secret = process.env.AUTH_SECRET;
package/mcq-test.cjs ADDED
@@ -0,0 +1,36 @@
1
+ import { z } from 'zod';
2
+
3
+ const worksheetModeSchema = z.enum(['practice', 'quiz']);
4
+ const worksheetDifficultyInputSchema = z.enum(['easy', 'medium', 'hard']);
5
+ const questionTypeSchema = z.enum([
6
+ 'MULTIPLE_CHOICE',
7
+ 'TEXT',
8
+ 'NUMERIC',
9
+ 'TRUE_FALSE',
10
+ 'MATCHING',
11
+ 'FILL_IN_THE_BLANK',
12
+ ]);
13
+
14
+
15
+ const worksheetPresetConfigSchema = z.object({
16
+ mode: worksheetModeSchema.default('practice'),
17
+ numQuestions: z.number().int().min(1).max(20).default(8),
18
+ difficulty: worksheetDifficultyInputSchema.default('medium'),
19
+ questionTypes: z.array(questionTypeSchema).optional(),
20
+ mcqRatio: z.number().min(0).max(1).optional(),
21
+ });
22
+
23
+ function test(mcqCount, numQuestions) {
24
+ const configOverride = {
25
+ questionTypes: ['MULTIPLE_CHOICE', 'TEXT'],
26
+ mcqRatio: mcqCount / Math.max(1, numQuestions),
27
+ };
28
+
29
+ const merged = {
30
+ ...worksheetPresetConfigSchema.parse({}),
31
+ ...configOverride,
32
+ };
33
+ console.log(`mcqCount: ${mcqCount}, numQuestions: ${numQuestions} -> mcqRatio: ${merged.mcqRatio}`);
34
+ }
35
+
36
+ test(4, 8);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goscribe/server",
3
- "version": "1.1.7",
3
+ "version": "1.3.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,6 +15,10 @@
15
15
  "dev": "tsx watch src/server.ts",
16
16
  "build": "npx prisma generate && tsc -p .",
17
17
  "start": "node --experimental-specifier-resolution=node dist/server.js",
18
+ "test": "tsx --test src/lib/worksheet-generation.test.ts",
19
+ "test:activity": "tsx --test src/lib/activity_log_service.test.ts src/lib/activity_human_description.test.ts"
20
+ },
21
+ "prisma": {
18
22
  "seed": "node --experimental-specifier-resolution=node prisma/seed.mjs"
19
23
  },
20
24
  "author": "",
@@ -36,11 +40,14 @@
36
40
  "express": "^5.1.0",
37
41
  "helmet": "^8.1.0",
38
42
  "morgan": "^1.10.1",
43
+ "nodemailer": "^8.0.1",
39
44
  "openai": "^6.3.0",
40
45
  "prisma": "^6.14.0",
41
46
  "pusher": "^5.2.0",
42
47
  "pusher-js": "^8.4.0",
48
+ "resend": "^6.9.2",
43
49
  "socket.io": "^4.8.1",
50
+ "stripe": "^20.4.1",
44
51
  "superjson": "^2.2.2",
45
52
  "uuid": "^13.0.0",
46
53
  "zod": "^4.1.1"
@@ -52,6 +59,7 @@
52
59
  "@types/express": "^5.0.3",
53
60
  "@types/morgan": "^1.9.10",
54
61
  "@types/node": "^24.3.0",
62
+ "@types/nodemailer": "^7.0.11",
55
63
  "ts-node": "^10.9.2",
56
64
  "ts-node-dev": "^2.0.0",
57
65
  "tsc-alias": "^1.8.16",
@@ -60,4 +68,4 @@
60
68
  "typescript": "^5.9.2",
61
69
  "typescript-transform-paths": "^3.5.5"
62
70
  }
63
- }
71
+ }