@goscribe/server 1.0.9 → 1.0.11

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.
@@ -0,0 +1,165 @@
1
+ # 🗄️ Database Setup Guide
2
+
3
+ ## 📋 Overview
4
+ This guide covers the database configuration for the Scribe server, including Prisma setup, environment variables, and troubleshooting common connection issues.
5
+
6
+ ---
7
+
8
+ ## 🔧 Environment Variables Required
9
+
10
+ ### Core Database Configuration
11
+ ```bash
12
+ # Pooled connection (for runtime queries)
13
+ DATABASE_URL="postgresql://<db_user>:<db_password>@aws-1-ap-southeast-1.pooler.supabase.com:5432/postgres?sslmode=require"
14
+
15
+ # Direct connection (for migrations and schema operations)
16
+ DIRECT_URL="postgresql://<db_user>:<db_password>@db.<project-ref>.supabase.co:5432/postgres?sslmode=require"
17
+ ```
18
+
19
+ ### 🔍 Where to Find These Values
20
+ 1. Go to your Supabase project dashboard
21
+ 2. Navigate to **Settings** → **Database**
22
+ 3. Copy the connection strings from:
23
+ - **Connection pooling** → `DATABASE_URL`
24
+ - **Direct connection** → `DIRECT_URL`
25
+
26
+ ---
27
+
28
+ ## 🚀 Quick Setup Steps
29
+
30
+ ### 1. Set Environment Variables
31
+ ```bash
32
+ # Option A: Export for current session
33
+ export DATABASE_URL="your_pooled_connection_string"
34
+ export DIRECT_URL="your_direct_connection_string"
35
+
36
+ # Option B: Add to .env file
37
+ echo "DATABASE_URL=your_pooled_connection_string" >> .env
38
+ echo "DIRECT_URL=your_direct_connection_string" >> .env
39
+ ```
40
+
41
+ ### 2. Generate Prisma Client
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ ### 3. Run Migrations (if needed)
47
+ ```bash
48
+ npx prisma migrate deploy
49
+ ```
50
+
51
+ ### 4. Seed Database (optional)
52
+ ```bash
53
+ npm run seed
54
+ ```
55
+
56
+ ---
57
+
58
+ ## 🏗️ Database Schema Overview
59
+
60
+ ### Core Models
61
+ - **User** - Authentication and user management
62
+ - **Workspace** - Project containers with folders
63
+ - **Channel** - Chat channels within workspaces
64
+ - **Chat** - Individual chat messages
65
+ - **Artifact** - AI-generated content (study guides, flashcards, etc.)
66
+ - **FileAsset** - User uploads and attachments
67
+
68
+ ### Key Relationships
69
+ ```
70
+ User → Workspaces → Channels → Chats
71
+ User → Artifacts → Versions/Questions/Flashcards
72
+ Workspace → FileAssets
73
+ ```
74
+
75
+ ---
76
+
77
+ ## 🐛 Troubleshooting
78
+
79
+ ### ❌ "Tenant or user not found" Error
80
+
81
+ **Cause:** Incorrect database credentials or connection string format
82
+
83
+ **Solutions:**
84
+ 1. **Verify credentials** in Supabase dashboard
85
+ 2. **Check connection string format:**
86
+ ```bash
87
+ # ✅ Correct format
88
+ postgresql://user:password@host:port/database?sslmode=require
89
+
90
+ # ❌ Common mistakes
91
+ postgresql://user:password@host:port/database # Missing sslmode
92
+ postgresql://user:password@host:port # Missing database name
93
+ ```
94
+
95
+ 3. **Ensure proper URL encoding** for special characters in passwords
96
+ 4. **Use direct connection** for migrations (not pooled)
97
+
98
+ ### ❌ Migration Failures
99
+
100
+ **Cause:** Using pooled connection for schema operations
101
+
102
+ **Solution:** Always use `DIRECT_URL` for migrations
103
+ ```bash
104
+ # ✅ Correct
105
+ DIRECT_URL="postgresql://user:pass@db.project.supabase.co:5432/postgres?sslmode=require"
106
+
107
+ # ❌ Wrong
108
+ DIRECT_URL="postgresql://user:pass@aws-1-ap-southeast-1.pooler.supabase.com:5432/postgres?sslmode=require"
109
+ ```
110
+
111
+ ### ❌ Connection Timeouts
112
+
113
+ **Solutions:**
114
+ 1. Check Supabase project status
115
+ 2. Verify network connectivity
116
+ 3. Ensure SSL mode is set to `require`
117
+ 4. Check if IP is whitelisted (if using IP restrictions)
118
+
119
+ ---
120
+
121
+ ## 📊 Database Operations
122
+
123
+ ### Available Scripts
124
+ ```bash
125
+ # Development
126
+ npm run dev # Start development server
127
+
128
+ # Database
129
+ npm run build # Generate Prisma client + build
130
+ npm run seed # Populate with sample data
131
+ npx prisma studio # Open database browser
132
+ npx prisma migrate dev # Create and apply migrations
133
+ npx prisma migrate deploy # Apply existing migrations
134
+ ```
135
+
136
+ ### Sample Data
137
+ The seed script creates:
138
+ - Demo user (`demo@example.com`)
139
+ - Sample workspace with artifacts
140
+ - Worksheet with mixed question types
141
+ - Flashcard set
142
+ - Study guide with versions
143
+
144
+ ---
145
+
146
+ ## 🔐 Security Notes
147
+
148
+ - **Never commit** `.env` files to version control
149
+ - **Use environment-specific** connection strings
150
+ - **Enable SSL** (`sslmode=require`) for all connections
151
+ - **Rotate credentials** regularly
152
+ - **Use connection pooling** for production workloads
153
+
154
+ ---
155
+
156
+ ## 📚 Additional Resources
157
+
158
+ - [Prisma Documentation](https://www.prisma.io/docs)
159
+ - [Supabase Database Guide](https://supabase.com/docs/guides/database)
160
+ - [PostgreSQL Connection Strings](https://www.postgresql.org/docs/current/libpq-connect.html)
161
+
162
+ ---
163
+
164
+ *Last updated: $(date)*
165
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goscribe/server",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,8 +1,8 @@
1
1
  import { TRPCError } from '@trpc/server';
2
2
 
3
3
  // External AI service configuration
4
- const AI_SERVICE_URL = 'https://hwln4560erf7pr-61016.proxy.runpod.net/upload';
5
- const AI_RESPONSE_URL = 'https://hwln4560erf7pr-61016.proxy.runpod.net/last_response';
4
+ const AI_SERVICE_URL = 'https://7gzvf7uib04yp9-61016.proxy.runpod.net/upload';
5
+ const AI_RESPONSE_URL = 'https://7gzvf7uib04yp9-61016.proxy.runpod.net/last_response';
6
6
 
7
7
  export interface AISession {
8
8
  id: string;
@@ -18,12 +18,13 @@ export class AISessionService {
18
18
  private sessions = new Map<string, AISession>();
19
19
 
20
20
  // Initialize a new AI session
21
- async initSession(workspaceId: string): Promise<AISession> {
21
+ async initSession(workspaceId: string, user: string): Promise<AISession> {
22
22
  const sessionId = `${workspaceId}`;
23
23
 
24
24
  const formData = new FormData();
25
25
  formData.append('command', 'init_session');
26
- formData.append('id', sessionId);
26
+ formData.append('session', sessionId);
27
+ formData.append('user', user);
27
28
 
28
29
  // Retry logic for AI service
29
30
  const maxRetries = 3;
@@ -170,7 +170,7 @@ export const flashcards = router({
170
170
  The user has also left you this prompt: ${input.prompt}
171
171
  `
172
172
  // Init AI session and seed with prompt as instruction
173
- const session = await aiSessionService.initSession(input.workspaceId);
173
+ const session = await aiSessionService.initSession(input.workspaceId, ctx.session.user.id);
174
174
  await aiSessionService.setInstruction(session.id, partialPrompt);
175
175
 
176
176
  await aiSessionService.startLLMSession(session.id);
@@ -402,7 +402,7 @@ export const worksheets = router({
402
402
 
403
403
  await PusherService.emitTaskComplete(input.workspaceId, 'worksheet_load_start', { source: 'prompt' });
404
404
 
405
- const session = await aiSessionService.initSession(input.workspaceId);
405
+ const session = await aiSessionService.initSession(input.workspaceId, ctx.session.user.id);
406
406
  await aiSessionService.setInstruction(session.id, `Create a worksheet with ${input.numQuestions} questions at ${input.difficulty} difficulty from this prompt. Return JSON.\n\nPrompt:\n${input.prompt}`);
407
407
  await aiSessionService.startLLMSession(session.id);
408
408
 
@@ -376,7 +376,7 @@ export const workspace = router({
376
376
 
377
377
  // Initialize AI session
378
378
  console.log('🤖 Initializing AI session...');
379
- const session = await aiSessionService.initSession(input.workspaceId);
379
+ const session = await aiSessionService.initSession(input.workspaceId, ctx.session.user.id);
380
380
  console.log('✅ AI session initialized', { sessionId: session.id });
381
381
 
382
382
  const fileObj = new File([fileBuffer], input.file.filename, { type: input.file.contentType });