@goscribe/server 1.0.8 → 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.
Files changed (58) hide show
  1. package/AUTH_FRONTEND_SPEC.md +21 -0
  2. package/CHAT_FRONTEND_SPEC.md +474 -0
  3. package/DATABASE_SETUP.md +165 -0
  4. package/MEETINGSUMMARY_FRONTEND_SPEC.md +28 -0
  5. package/PODCAST_FRONTEND_SPEC.md +595 -0
  6. package/STUDYGUIDE_FRONTEND_SPEC.md +18 -0
  7. package/WORKSHEETS_FRONTEND_SPEC.md +26 -0
  8. package/WORKSPACE_FRONTEND_SPEC.md +47 -0
  9. package/dist/lib/ai-session.d.ts +26 -0
  10. package/dist/lib/ai-session.js +343 -0
  11. package/dist/lib/inference.d.ts +2 -0
  12. package/dist/lib/inference.js +21 -0
  13. package/dist/lib/pusher.d.ts +14 -0
  14. package/dist/lib/pusher.js +94 -0
  15. package/dist/lib/storage.d.ts +10 -2
  16. package/dist/lib/storage.js +63 -6
  17. package/dist/routers/_app.d.ts +840 -58
  18. package/dist/routers/_app.js +6 -0
  19. package/dist/routers/ai-session.d.ts +0 -0
  20. package/dist/routers/ai-session.js +1 -0
  21. package/dist/routers/auth.d.ts +1 -0
  22. package/dist/routers/auth.js +6 -4
  23. package/dist/routers/chat.d.ts +171 -0
  24. package/dist/routers/chat.js +270 -0
  25. package/dist/routers/flashcards.d.ts +37 -0
  26. package/dist/routers/flashcards.js +128 -0
  27. package/dist/routers/meetingsummary.d.ts +0 -0
  28. package/dist/routers/meetingsummary.js +377 -0
  29. package/dist/routers/podcast.d.ts +277 -0
  30. package/dist/routers/podcast.js +847 -0
  31. package/dist/routers/studyguide.d.ts +54 -0
  32. package/dist/routers/studyguide.js +125 -0
  33. package/dist/routers/worksheets.d.ts +138 -51
  34. package/dist/routers/worksheets.js +317 -7
  35. package/dist/routers/workspace.d.ts +162 -7
  36. package/dist/routers/workspace.js +440 -8
  37. package/dist/server.js +6 -2
  38. package/package.json +11 -4
  39. package/prisma/migrations/20250826124819_add_worksheet_difficulty_and_estimated_time/migration.sql +213 -0
  40. package/prisma/migrations/20250826133236_add_worksheet_question_progress/migration.sql +31 -0
  41. package/prisma/migrations/migration_lock.toml +3 -0
  42. package/prisma/schema.prisma +87 -6
  43. package/prisma/seed.mjs +135 -0
  44. package/src/lib/ai-session.ts +412 -0
  45. package/src/lib/inference.ts +21 -0
  46. package/src/lib/pusher.ts +104 -0
  47. package/src/lib/storage.ts +89 -6
  48. package/src/routers/_app.ts +6 -0
  49. package/src/routers/auth.ts +8 -4
  50. package/src/routers/chat.ts +275 -0
  51. package/src/routers/flashcards.ts +142 -0
  52. package/src/routers/meetingsummary.ts +416 -0
  53. package/src/routers/podcast.ts +934 -0
  54. package/src/routers/studyguide.ts +144 -0
  55. package/src/routers/worksheets.ts +336 -7
  56. package/src/routers/workspace.ts +487 -8
  57. package/src/server.ts +7 -2
  58. package/test-ai-integration.js +134 -0
@@ -0,0 +1,21 @@
1
+ ## Auth Frontend Spec
2
+
3
+ ### Endpoints (tRPC)
4
+ - **auth.signup**: `{ name: string; email: string; password: string }` → `{ id: string; email: string; name: string }`
5
+ - **auth.login**: `{ email: string; password: string }` → `{ id: string; email: string; name: string; image?: string | null; token: string }` (also sets `auth_token` cookie)
6
+ - **auth.getSession**: `void` → `{ user: { id: string; email: string; name: string; image?: string | null } }`
7
+ - **auth.logout**: `void` → `{ success: true }` (clears `auth_token` cookie)
8
+
9
+ ### Cookie & Token
10
+ - On login, server sets `auth_token` cookie (HTTP-only). Value is HMAC of base64 user id with `AUTH_SECRET`.
11
+ - Cookie attributes:
12
+ - `httpOnly: true`
13
+ - `secure: true` in production
14
+ - `sameSite: 'none'` in production, `'lax'` in dev
15
+ - `domain: 'server-w8mz.onrender.com'` in production
16
+ - `maxAge: 30 days`
17
+
18
+ ### UX Notes
19
+ - After `auth.login`, rely on cookie for session; also keep returned `token` if needed for client-side display.
20
+ - Call `auth.getSession` on app bootstrap; if it throws, redirect to login.
21
+ - On `auth.logout`, clear local user state immediately (optimistic) and navigate to login.
@@ -0,0 +1,474 @@
1
+ # Chat Frontend Integration Specification
2
+
3
+ ## Overview
4
+ This document outlines the frontend requirements for integrating with the chat functionality, including real-time messaging, channel management, and user interactions.
5
+
6
+ ## Real-Time Events (Pusher)
7
+
8
+ ### Event Channels
9
+ Chat events are broadcast on different channels:
10
+ - Channel events: `workspace_{workspaceId}`
11
+ - Message events: `{channelId}` (the channelId itself is used as the channel name)
12
+
13
+ ### Event Types
14
+
15
+ #### 1. Channel Management Events
16
+ ```typescript
17
+ // New Channel Created
18
+ {
19
+ event: '{workspaceId}_new_channel',
20
+ data: {
21
+ channelId: string,
22
+ workspaceId: string,
23
+ name: string,
24
+ createdAt: string
25
+ }
26
+ }
27
+
28
+ // Channel Edited
29
+ {
30
+ event: '{workspaceId}_edit_channel',
31
+ data: {
32
+ channelId: string,
33
+ workspaceId: string,
34
+ name: string
35
+ }
36
+ }
37
+
38
+ // Channel Removed
39
+ {
40
+ event: '{workspaceId}_remove_channel',
41
+ data: {
42
+ channelId: string,
43
+ deletedAt: string
44
+ }
45
+ }
46
+ ```
47
+
48
+ #### 2. Message Events
49
+ ```typescript
50
+ // New Message Posted
51
+ {
52
+ event: '{channelId}_new_message',
53
+ data: {
54
+ chatId: string,
55
+ channelId: string,
56
+ userId: string,
57
+ message: string,
58
+ createdAt: string
59
+ }
60
+ }
61
+
62
+ // Message Edited
63
+ {
64
+ event: '{channelId}_edit_message',
65
+ data: {
66
+ chatId: string,
67
+ channelId: string,
68
+ userId: string,
69
+ message: string,
70
+ updatedAt: string
71
+ }
72
+ }
73
+
74
+ // Message Deleted
75
+ {
76
+ event: '{channelId}_delete_message',
77
+ data: {
78
+ chatId: string,
79
+ channelId: string,
80
+ userId: string,
81
+ deletedAt: string
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## Data Types
87
+
88
+ ### Channel
89
+ ```typescript
90
+ interface Channel {
91
+ id: string;
92
+ workspaceId: string;
93
+ name: string;
94
+ createdAt: string;
95
+ updatedAt: string;
96
+ chats?: ChatMessage[]; // Includes user information for each message
97
+ }
98
+ ```
99
+
100
+ ### Chat Message
101
+ ```typescript
102
+ interface ChatMessage {
103
+ id: string;
104
+ channelId: string;
105
+ userId: string;
106
+ message: string;
107
+ createdAt: string;
108
+ updatedAt: string;
109
+ user: {
110
+ id: string;
111
+ name: string;
112
+ image?: string;
113
+ };
114
+ }
115
+ ```
116
+
117
+ ### User Information
118
+ All messages include user information with:
119
+ - `id`: User ID
120
+ - `name`: User display name
121
+ - `image`: User avatar (optional)
122
+
123
+ ## API Endpoints
124
+
125
+ ### 1. Get Channels
126
+ ```typescript
127
+ // GET /trpc/chat.getChannels
128
+ {
129
+ input: {
130
+ workspaceId: string;
131
+ }
132
+ }
133
+ // Returns all channels for a workspace with messages and user info
134
+ // Creates "General" channel if no channels exist
135
+ ```
136
+
137
+ ### 2. Get Channel
138
+ ```typescript
139
+ // GET /trpc/chat.getChannel
140
+ {
141
+ input: {
142
+ workspaceId?: string;
143
+ channelId?: string;
144
+ }
145
+ }
146
+ // Returns specific channel with messages and user info
147
+ // Creates "General" channel if workspaceId provided and no channelId
148
+ ```
149
+
150
+ ### 3. Create Channel
151
+ ```typescript
152
+ // POST /trpc/chat.createChannel
153
+ {
154
+ input: {
155
+ workspaceId: string;
156
+ name: string;
157
+ }
158
+ }
159
+ // Creates new channel and returns with messages and user info
160
+ ```
161
+
162
+ ### 4. Edit Channel
163
+ ```typescript
164
+ // POST /trpc/chat.editChannel
165
+ {
166
+ input: {
167
+ workspaceId: string;
168
+ channelId: string;
169
+ name: string;
170
+ }
171
+ }
172
+ // Updates channel name and returns with messages and user info
173
+ ```
174
+
175
+ ### 5. Remove Channel
176
+ ```typescript
177
+ // POST /trpc/chat.removeChannel
178
+ {
179
+ input: {
180
+ workspaceId: string;
181
+ channelId: string;
182
+ }
183
+ }
184
+ // Deletes channel and returns { success: true }
185
+ ```
186
+
187
+ ### 6. Post Message
188
+ ```typescript
189
+ // POST /trpc/chat.postMessage
190
+ {
191
+ input: {
192
+ channelId: string;
193
+ message: string;
194
+ }
195
+ }
196
+ // Creates new message and returns with user info
197
+ ```
198
+
199
+ ### 7. Edit Message
200
+ ```typescript
201
+ // POST /trpc/chat.editMessage
202
+ {
203
+ input: {
204
+ chatId: string;
205
+ message: string;
206
+ }
207
+ }
208
+ // Updates message and returns with user info
209
+ // Only allows editing own messages
210
+ ```
211
+
212
+ ### 8. Delete Message
213
+ ```typescript
214
+ // POST /trpc/chat.deleteMessage
215
+ {
216
+ input: {
217
+ chatId: string;
218
+ }
219
+ }
220
+ // Deletes message and returns { success: true }
221
+ // Only allows deleting own messages
222
+ ```
223
+
224
+ ## UI Components
225
+
226
+ ### 1. Channel List Component
227
+ ```typescript
228
+ interface ChannelList {
229
+ channels: Channel[];
230
+ currentChannelId?: string;
231
+ onChannelSelect: (channelId: string) => void;
232
+ onCreateChannel: (name: string) => void;
233
+ onEditChannel: (channelId: string, name: string) => void;
234
+ onDeleteChannel: (channelId: string) => void;
235
+ }
236
+ ```
237
+
238
+ ### 2. Chat Interface Component
239
+ ```typescript
240
+ interface ChatInterface {
241
+ channelId: string;
242
+ messages: ChatMessage[];
243
+ currentUserId: string;
244
+ onSendMessage: (message: string) => void;
245
+ onEditMessage: (chatId: string, message: string) => void;
246
+ onDeleteMessage: (chatId: string) => void;
247
+ isLoading: boolean;
248
+ }
249
+ ```
250
+
251
+ ### 3. Message Component
252
+ ```typescript
253
+ interface MessageComponent {
254
+ message: ChatMessage;
255
+ isOwnMessage: boolean;
256
+ onEdit: (chatId: string, newMessage: string) => void;
257
+ onDelete: (chatId: string) => void;
258
+ }
259
+ ```
260
+
261
+ ## User Experience Flow
262
+
263
+ ### 1. Channel Management
264
+ 1. User opens workspace
265
+ 2. Load all channels using `getChannels` endpoint
266
+ 3. System automatically creates "General" channel if no channels exist
267
+ 4. User can create new channels
268
+ 5. User can edit channel names
269
+ 6. User can delete channels (with confirmation)
270
+ 7. Real-time updates when channels are created/edited/deleted
271
+
272
+ ### 2. Messaging Flow
273
+ 1. User selects a channel
274
+ 2. Load existing messages for the channel (includes user info)
275
+ 3. User types and sends message
276
+ 4. Message appears immediately (optimistic update)
277
+ 5. Real-time notification to other users
278
+ 6. Handle message editing and deletion
279
+ 7. Show user names and avatars for all messages
280
+
281
+ ### 3. Message Management
282
+ 1. User can edit their own messages only
283
+ 2. User can delete their own messages only
284
+ 3. Real-time updates for message changes
285
+ 4. Proper error handling for unauthorized actions
286
+
287
+ ## Real-Time Implementation
288
+
289
+ ### PusherService Methods
290
+ The chat system uses two different PusherService methods:
291
+ - `emitTaskComplete(workspaceId, event, data)` - For channel management events
292
+ - `emitChannelEvent(channelId, event, data)` - For message events (channel-specific)
293
+
294
+ ### 1. Initial Channel Loading
295
+ ```typescript
296
+ // Load all channels for a workspace
297
+ const channels = await trpc.chat.getChannels.query({
298
+ workspaceId: workspaceId
299
+ });
300
+
301
+ // This will automatically create a "General" channel if none exist
302
+ // All channels include messages with user information
303
+ ```
304
+
305
+ ### 2. Channel Events (Workspace Channel)
306
+ ```typescript
307
+ // Subscribe to workspace channel events
308
+ const workspaceChannel = pusher.subscribe(`workspace_${workspaceId}`);
309
+
310
+ workspaceChannel.bind(`${workspaceId}_new_channel`, (data) => {
311
+ // Add new channel to list
312
+ setChannels(prev => [...prev, data]);
313
+ });
314
+
315
+ workspaceChannel.bind(`${workspaceId}_edit_channel`, (data) => {
316
+ // Update channel name in list
317
+ setChannels(prev => prev.map(ch =>
318
+ ch.id === data.channelId ? { ...ch, name: data.name } : ch
319
+ ));
320
+ });
321
+
322
+ workspaceChannel.bind(`${workspaceId}_remove_channel`, (data) => {
323
+ // Remove channel from list
324
+ setChannels(prev => prev.filter(ch => ch.id !== data.channelId));
325
+ });
326
+ ```
327
+
328
+ ### 3. Message Events (Channel-Specific)
329
+ ```typescript
330
+ // Subscribe to message events for specific channel
331
+ const messageChannel = pusher.subscribe(channelId);
332
+
333
+ messageChannel.bind(`${channelId}_new_message`, (data) => {
334
+ // Add new message to chat
335
+ setMessages(prev => [...prev, data]);
336
+ });
337
+
338
+ messageChannel.bind(`${channelId}_edit_message`, (data) => {
339
+ // Update message in chat
340
+ setMessages(prev => prev.map(msg =>
341
+ msg.id === data.chatId ? { ...msg, message: data.message, updatedAt: data.updatedAt } : msg
342
+ ));
343
+ });
344
+
345
+ messageChannel.bind(`${channelId}_delete_message`, (data) => {
346
+ // Remove message from chat
347
+ setMessages(prev => prev.filter(msg => msg.id !== data.chatId));
348
+ });
349
+ ```
350
+
351
+ ## Error Handling
352
+
353
+ ### 1. Channel Errors
354
+ - Channel not found
355
+ - Unauthorized to edit/delete channel
356
+ - Duplicate channel names
357
+
358
+ ### 2. Message Errors
359
+ - Message not found
360
+ - Unauthorized to edit/delete message (only own messages)
361
+ - Message too long
362
+ - Rate limiting
363
+
364
+ ### 3. Network Errors
365
+ - Connection lost
366
+ - Retry logic for failed operations
367
+ - Offline indicators
368
+
369
+ ## Loading States
370
+
371
+ ### 1. Channel Loading
372
+ ```typescript
373
+ interface ChannelLoadingState {
374
+ isLoading: boolean;
375
+ error?: string;
376
+ channels: Channel[];
377
+ }
378
+ ```
379
+
380
+ ### 2. Message Loading
381
+ ```typescript
382
+ interface MessageLoadingState {
383
+ isLoading: boolean;
384
+ isSending: boolean;
385
+ error?: string;
386
+ messages: ChatMessage[];
387
+ }
388
+ ```
389
+
390
+ ## Security & Authorization
391
+
392
+ ### 1. Message Ownership
393
+ - Users can only edit their own messages
394
+ - Users can only delete their own messages
395
+ - Proper validation on server side
396
+
397
+ ### 2. Channel Access
398
+ - Users can only access channels in their workspaces
399
+ - Proper workspace membership validation
400
+
401
+ ### 3. Input Validation
402
+ - Message content validation
403
+ - Channel name validation
404
+ - Rate limiting for message sending
405
+
406
+ ## Performance Considerations
407
+
408
+ ### 1. Message Loading
409
+ - All messages include user info (no additional queries needed)
410
+ - Efficient database queries with includes
411
+ - Proper indexing on channelId and userId
412
+
413
+ ### 2. Real-time Updates
414
+ - Separate channels for workspace and message events
415
+ - Efficient event routing
416
+ - Optimized payload sizes
417
+
418
+ ### 3. Memory Management
419
+ - Clean up Pusher subscriptions when switching channels
420
+ - Limit message history in memory
421
+ - Garbage collection for old messages
422
+
423
+ ## Testing Requirements
424
+
425
+ ### 1. Unit Tests
426
+ - Component rendering with user info
427
+ - Message formatting and display
428
+ - Channel management logic
429
+
430
+ ### 2. Integration Tests
431
+ - API interactions with user data
432
+ - Real-time event handling
433
+ - Authorization scenarios
434
+
435
+ ### 3. E2E Tests
436
+ - Complete messaging flow with user attribution
437
+ - Channel management
438
+ - Real-time synchronization
439
+
440
+ ## Browser Support
441
+
442
+ ### Required
443
+ - Chrome 90+
444
+ - Firefox 88+
445
+ - Safari 14+
446
+ - Edge 90+
447
+
448
+ ### Real-time Support
449
+ - WebSocket support
450
+ - Pusher client compatibility
451
+ - EventSource fallback
452
+
453
+ ## Future Enhancements
454
+
455
+ ### 1. Advanced Features
456
+ - Message reactions
457
+ - File attachments
458
+ - Voice messages
459
+ - Message threading
460
+ - Read receipts
461
+
462
+ ### 2. UI Improvements
463
+ - Typing indicators
464
+ - Message search
465
+ - Message pinning
466
+ - Channel categories
467
+ - Dark mode support
468
+
469
+ ### 3. Performance Optimizations
470
+ - Message pagination
471
+ - Virtual scrolling
472
+ - Offline support
473
+ - Background sync
474
+ - Push notifications
@@ -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
+
@@ -0,0 +1,28 @@
1
+ ## Meeting Summary Frontend Spec
2
+
3
+ Note: The `meetingsummary` router is currently commented out. This spec outlines the intended API based on the commented code and typical flows, so the frontend contract is ready when implementation resumes.
4
+
5
+ ### Proposed Endpoints (tRPC)
6
+ - **meetingsummary.listSummaries**: `{ workspaceId: string }` → `Artifact[]` (type: `MEETING_SUMMARY`, latest version included)
7
+ - **meetingsummary.getSummary**: `{ summaryId: string }` → `Artifact & { versions: Version[] }`
8
+ - **meetingsummary.uploadFile**: `{ workspaceId: string; fileName: string; fileBuffer: string /* base64 */; mimeType: string; title?: string }` → `{ id: string; title: string; summary: SummaryData; transcript: string }`
9
+ - **meetingsummary.processSchema**: `{ workspaceId: string; meetingData: MeetingSchema }` → `{ id: string; title: string; summary: SummaryData; originalData: MeetingSchema }`
10
+ - **meetingsummary.updateSummary**: `{ summaryId: string; title?: string; content?: string }` → `Artifact`
11
+ - **meetingsummary.deleteSummary**: `{ summaryId: string }` → `true`
12
+ - **meetingsummary.getVersions**: `{ summaryId: string }` → `Version[]`
13
+
14
+ ### Types (simplified)
15
+ - **Artifact**: `{ id; workspaceId; type: 'MEETING_SUMMARY'; title; content?; createdAt; updatedAt }`
16
+ - **Version**: `{ id; artifactId; version: number; content: string; createdAt }`
17
+ - **MeetingSchema**: `{ title: string; participants: string[]; date: string; duration?: string; agenda?: string[]; transcript?: string; notes?: string }`
18
+ - **SummaryData**: `{ keyPoints: string[]; actionItems: string[]; decisions: string[]; nextSteps: string[]; insights?: string[]; summary: string }`
19
+
20
+ ### Upload Flow (when implemented)
21
+ 1. Validate file type (mp3/mp4/wav/m4a).
22
+ 2. Upload base64 file; backend transcribes (Whisper) then summarizes (GPT), stores artifact + version.
23
+ 3. Return summary JSON and transcript.
24
+
25
+ ### UX Notes
26
+ - Show parsing progress and handle large files.
27
+ - Provide manual schema entry as fallback (processSchema).
28
+ - Keep version history for edits; show latest version by default.