@goscribe/server 1.0.9 → 1.0.10
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/DATABASE_SETUP.md +165 -0
- package/package.json +1 -1
- package/src/lib/ai-session.ts +5 -4
- package/src/routers/flashcards.ts +1 -1
- package/src/routers/worksheets.ts +1 -1
- package/src/routers/workspace.ts +1 -1
|
@@ -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
package/src/lib/ai-session.ts
CHANGED
|
@@ -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://
|
|
5
|
-
const AI_RESPONSE_URL = 'https://
|
|
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('
|
|
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
|
|
package/src/routers/workspace.ts
CHANGED
|
@@ -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 });
|