@vezlo/assistant-server 1.3.0 → 2.0.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 (113) hide show
  1. package/README.md +140 -43
  2. package/bin/vezlo-server.js +1 -1
  3. package/database-schema.sql +193 -33
  4. package/dist/knexfile.d.ts.map +1 -1
  5. package/dist/knexfile.js +17 -8
  6. package/dist/knexfile.js.map +1 -1
  7. package/dist/src/config/database.d.ts.map +1 -1
  8. package/dist/src/config/database.js +9 -1
  9. package/dist/src/config/database.js.map +1 -1
  10. package/dist/src/config/global.d.ts.map +1 -1
  11. package/dist/src/config/global.js +5 -2
  12. package/dist/src/config/global.js.map +1 -1
  13. package/dist/src/config/knex.d.ts.map +1 -1
  14. package/dist/src/config/knex.js +22 -2
  15. package/dist/src/config/knex.js.map +1 -1
  16. package/dist/src/config/swagger.d.ts.map +1 -1
  17. package/dist/src/config/swagger.js +34 -73
  18. package/dist/src/config/swagger.js.map +1 -1
  19. package/dist/src/controllers/ApiKeyController.d.ts +17 -0
  20. package/dist/src/controllers/ApiKeyController.d.ts.map +1 -0
  21. package/dist/src/controllers/ApiKeyController.js +84 -0
  22. package/dist/src/controllers/ApiKeyController.js.map +1 -0
  23. package/dist/src/controllers/AuthController.d.ts +14 -0
  24. package/dist/src/controllers/AuthController.d.ts.map +1 -0
  25. package/dist/src/controllers/AuthController.js +212 -0
  26. package/dist/src/controllers/AuthController.js.map +1 -0
  27. package/dist/src/controllers/ChatController.d.ts +8 -5
  28. package/dist/src/controllers/ChatController.d.ts.map +1 -1
  29. package/dist/src/controllers/ChatController.js +139 -31
  30. package/dist/src/controllers/ChatController.js.map +1 -1
  31. package/dist/src/controllers/KnowledgeController.d.ts +5 -4
  32. package/dist/src/controllers/KnowledgeController.d.ts.map +1 -1
  33. package/dist/src/controllers/KnowledgeController.js +54 -16
  34. package/dist/src/controllers/KnowledgeController.js.map +1 -1
  35. package/dist/src/middleware/auth.d.ts +51 -0
  36. package/dist/src/middleware/auth.d.ts.map +1 -0
  37. package/dist/src/middleware/auth.js +232 -0
  38. package/dist/src/middleware/auth.js.map +1 -0
  39. package/dist/src/middleware/errorHandler.d.ts.map +1 -1
  40. package/dist/src/middleware/errorHandler.js +13 -19
  41. package/dist/src/middleware/errorHandler.js.map +1 -1
  42. package/dist/src/migrations/001_initial_schema.d.ts.map +1 -1
  43. package/dist/src/migrations/001_initial_schema.js +39 -64
  44. package/dist/src/migrations/001_initial_schema.js.map +1 -1
  45. package/dist/src/migrations/002_multitenancy_schema.d.ts +4 -0
  46. package/dist/src/migrations/002_multitenancy_schema.d.ts.map +1 -0
  47. package/dist/src/migrations/002_multitenancy_schema.js +119 -0
  48. package/dist/src/migrations/002_multitenancy_schema.js.map +1 -0
  49. package/dist/src/schemas/AuthSchemas.d.ts +89 -0
  50. package/dist/src/schemas/AuthSchemas.d.ts.map +1 -0
  51. package/dist/src/schemas/AuthSchemas.js +63 -0
  52. package/dist/src/schemas/AuthSchemas.js.map +1 -0
  53. package/dist/src/schemas/CommonSchemas.d.ts +62 -0
  54. package/dist/src/schemas/CommonSchemas.d.ts.map +1 -0
  55. package/dist/src/schemas/CommonSchemas.js +65 -0
  56. package/dist/src/schemas/CommonSchemas.js.map +1 -0
  57. package/dist/src/schemas/ConversationSchemas.d.ts +64 -27
  58. package/dist/src/schemas/ConversationSchemas.d.ts.map +1 -1
  59. package/dist/src/schemas/ConversationSchemas.js +28 -9
  60. package/dist/src/schemas/ConversationSchemas.js.map +1 -1
  61. package/dist/src/schemas/FeedbackSchemas.d.ts +43 -5
  62. package/dist/src/schemas/FeedbackSchemas.d.ts.map +1 -1
  63. package/dist/src/schemas/FeedbackSchemas.js +20 -2
  64. package/dist/src/schemas/FeedbackSchemas.js.map +1 -1
  65. package/dist/src/schemas/KnowledgeSchemas.d.ts +114 -35
  66. package/dist/src/schemas/KnowledgeSchemas.d.ts.map +1 -1
  67. package/dist/src/schemas/KnowledgeSchemas.js +58 -16
  68. package/dist/src/schemas/KnowledgeSchemas.js.map +1 -1
  69. package/dist/src/schemas/MessageSchemas.d.ts +57 -8
  70. package/dist/src/schemas/MessageSchemas.d.ts.map +1 -1
  71. package/dist/src/schemas/MessageSchemas.js +22 -3
  72. package/dist/src/schemas/MessageSchemas.js.map +1 -1
  73. package/dist/src/schemas/index.d.ts +410 -68
  74. package/dist/src/schemas/index.d.ts.map +1 -1
  75. package/dist/src/schemas/index.js +8 -2
  76. package/dist/src/schemas/index.js.map +1 -1
  77. package/dist/src/server.js +1047 -615
  78. package/dist/src/server.js.map +1 -1
  79. package/dist/src/services/AIService.d.ts +1 -2
  80. package/dist/src/services/AIService.d.ts.map +1 -1
  81. package/dist/src/services/AIService.js +6 -32
  82. package/dist/src/services/AIService.js.map +1 -1
  83. package/dist/src/services/ApiKeyService.d.ts +38 -0
  84. package/dist/src/services/ApiKeyService.d.ts.map +1 -0
  85. package/dist/src/services/ApiKeyService.js +123 -0
  86. package/dist/src/services/ApiKeyService.js.map +1 -0
  87. package/dist/src/services/KnowledgeBaseService.d.ts +2 -2
  88. package/dist/src/services/KnowledgeBaseService.d.ts.map +1 -1
  89. package/dist/src/services/KnowledgeBaseService.js +9 -2
  90. package/dist/src/services/KnowledgeBaseService.js.map +1 -1
  91. package/dist/src/services/MigrationService.d.ts +1 -1
  92. package/dist/src/services/MigrationService.d.ts.map +1 -1
  93. package/dist/src/services/MigrationService.js +4 -8
  94. package/dist/src/services/MigrationService.js.map +1 -1
  95. package/dist/src/services/SetupService.d.ts +102 -0
  96. package/dist/src/services/SetupService.d.ts.map +1 -0
  97. package/dist/src/services/SetupService.js +343 -0
  98. package/dist/src/services/SetupService.js.map +1 -0
  99. package/dist/src/storage/ConversationRepository.d.ts.map +1 -1
  100. package/dist/src/storage/ConversationRepository.js +42 -8
  101. package/dist/src/storage/ConversationRepository.js.map +1 -1
  102. package/dist/src/storage/MessageRepository.d.ts.map +1 -1
  103. package/dist/src/storage/MessageRepository.js +23 -27
  104. package/dist/src/storage/MessageRepository.js.map +1 -1
  105. package/dist/src/types/index.d.ts +0 -8
  106. package/dist/src/types/index.d.ts.map +1 -1
  107. package/env.example +7 -5
  108. package/knexfile.ts +17 -8
  109. package/package.json +25 -16
  110. package/scripts/generate-key.js +124 -0
  111. package/scripts/seed-default.js +72 -0
  112. package/scripts/setup.js +410 -149
  113. package/scripts/validate-db.js +46 -13
package/README.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  🚀 **Production-ready Node.js/TypeScript API server** for the Vezlo AI Assistant platform - Complete backend APIs with Docker deployment and database migrations.
4
4
 
5
+ ## 🚨 Breaking Change Notice (v2.0.0)
6
+
7
+ **This version introduces multi-tenancy support with breaking changes. Existing data will not be migrated automatically.**
8
+
9
+ ### Migration Required
10
+ - **Database Schema**: New authentication and multi-tenancy tables
11
+ - **Auth Model**: Endpoints now use a mix of auth modes — some support JWT or API key, and select public endpoints remain for the chat widget
12
+ - **Data Structure**: Foreign key relationships updated for multi-tenancy
13
+
14
+ ### Quick Migration Steps
15
+ 1. **Upgrade**: `npm install @vezlo/assistant-server@latest`
16
+ 2. **Run migrations**: `npm run migrate:latest`
17
+ 3. **Setup**: `npm run seed-default`
18
+
19
+ See [CHANGELOG.md](./CHANGELOG.md) for complete migration guide.
20
+
21
+ ---
22
+
5
23
  ## 🏗️ Architecture
6
24
 
7
25
  - **Backend APIs** - RESTful API endpoints for AI chat and knowledge management
@@ -32,11 +50,25 @@ cd assistant-server
32
50
  npm install
33
51
  ```
34
52
 
53
+ ## 🏪 Vercel Marketplace Integration
54
+
55
+ **🚀 Recommended for Vercel Users** - Deploy with automated setup:
56
+
57
+ [![Install on Vercel](https://vercel.com/button)](https://vercel.com/marketplace/vezlo-assistant-server)
58
+
59
+ The Vercel Marketplace integration provides:
60
+ - **Guided Configuration** - Step-by-step setup wizard
61
+ - **Automatic Environment Setup** - No manual configuration needed
62
+ - **Database Migration** - Automatic table creation
63
+ - **Production Optimization** - Optimized for Vercel's serverless platform
64
+
65
+ [Learn more about the marketplace integration →](https://vercel.com/marketplace/vezlo-assistant-server)
66
+
35
67
  ## 🚀 Quick Start (Interactive Setup)
36
68
 
37
69
  ### Prerequisites
38
70
  - Node.js 20+ and npm 9+
39
- - Supabase project (or PostgreSQL database)
71
+ - Supabase project
40
72
  - OpenAI API key
41
73
 
42
74
  ### Easy Setup with Interactive Wizard
@@ -55,10 +87,13 @@ npm run setup
55
87
  ```
56
88
 
57
89
  The wizard will guide you through:
58
- 1. **Database Configuration** - Choose Supabase or PostgreSQL
59
- 2. **OpenAI API Setup** - Configure your AI model
60
- 3. **Automatic Table Creation** - Creates all required database tables
61
- 4. **Environment File Generation** - Saves configuration to .env
90
+ 1. **Supabase Configuration** - URL, Service Role Key, DB host/port/name/user/password (with defaults)
91
+ 2. **OpenAI Configuration** - API key, model, temperature, max tokens
92
+ 3. **Validation (non‑blocking)** - Tests Supabase API and DB connectivity
93
+ 4. **Migrations** - Runs Knex migrations if DB validation passes; otherwise shows how to run later
94
+ 5. **Environment** - Generates `.env` (does not overwrite if it already exists)
95
+ 6. **Default Data Seeding** - Creates default admin user and company
96
+ 7. **API Key Generation** - Generates API key for the default company
62
97
 
63
98
  After setup completes, start the server:
64
99
 
@@ -107,22 +142,31 @@ AI_MODEL=gpt-4o
107
142
  MIGRATION_SECRET_KEY=your-secure-migration-key-here
108
143
  ```
109
144
 
110
- #### 3. Setup Database Tables
145
+ #### 3. Run Database Migrations (Recommended)
146
+ ```bash
147
+ # Using Knex migrations (primary method)
148
+ npm run migrate:latest
149
+
150
+ # Or via API after server is running
151
+ curl "http://localhost:3000/api/migrate?key=$MIGRATION_SECRET_KEY"
152
+ ```
111
153
 
112
- **Option A: Automated Setup**
154
+ #### 4. Create Default Admin & Generate API Key
113
155
  ```bash
114
- vezlo-setup # Run wizard and choose option 3 to use existing .env
156
+ # Create default admin user and company (if not exists)
157
+ npm run seed-default
158
+
159
+ # Generate API key for library integration
160
+ npm run generate-key
115
161
  ```
116
162
 
117
- **Option B: Manual SQL**
163
+ Optional fallback (not recommended if using migrations):
118
164
  ```bash
119
- # Copy schema to Supabase SQL Editor
165
+ # Run raw SQL in Supabase Dashboard → SQL Editor
120
166
  cat database-schema.sql
121
-
122
- # Then execute in Supabase Dashboard → SQL Editor
123
167
  ```
124
168
 
125
- #### 4. Validate Setup
169
+ #### 5. Validate Setup
126
170
 
127
171
  ```bash
128
172
  # Verify database connection and tables
@@ -132,7 +176,7 @@ vezlo-validate
132
176
  npm run validate
133
177
  ```
134
178
 
135
- #### 5. Start Server
179
+ #### 6. Start Server
136
180
 
137
181
  ```bash
138
182
  # If installed globally
@@ -148,7 +192,7 @@ npm run build && npm start
148
192
  ### Docker Deployment
149
193
 
150
194
  ```bash
151
- # Start with Docker Compose
195
+ # Start with Docker Compose (uses .env from project root)
152
196
  docker-compose up -d
153
197
 
154
198
  # View logs
@@ -157,19 +201,36 @@ docker-compose logs -f vezlo-server
157
201
 
158
202
  ## ☁️ Vercel Deployment
159
203
 
160
- Deploy to Vercel's serverless platform with one click:
204
+ Deploy to Vercel's serverless platform with multiple options. The Marketplace integration collects your credentials during configuration and sets environment variables automatically.
205
+
206
+ ### Option 1: Vercel Marketplace Integration (Recommended)
207
+
208
+ **🚀 Deploy via Vercel Marketplace** - Automated setup with guided configuration:
209
+
210
+ [![Install on Vercel](https://vercel.com/button)](https://vercel.com/marketplace/vezlo-assistant-server)
161
211
 
162
- ### One-Click Deploy
212
+ **Benefits:**
213
+ - ✅ **Guided Setup** - Step-by-step configuration wizard
214
+ - ✅ **Automatic Environment Variables** - No manual env var configuration needed
215
+ - ✅ **Database Migration** - Automatic table creation and schema setup
216
+ - ✅ **Production Ready** - Optimized for Vercel's serverless platform
163
217
 
164
- [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vezlo/assistant-server&env=SUPABASE_URL,SUPABASE_ANON_KEY,SUPABASE_SERVICE_KEY,SUPABASE_DB_HOST,SUPABASE_DB_PORT,SUPABASE_DB_NAME,SUPABASE_DB_USER,SUPABASE_DB_PASSWORD,OPENAI_API_KEY,MIGRATION_SECRET_KEY&envDescription=Required%20environment%20variables&envLink=https://github.com/vezlo/assistant-server/blob/main/env.example)
218
+ **After Installation:**
219
+ 1. Run the migration URL: `https://your-project.vercel.app/api/migrate?key=YOUR_MIGRATION_SECRET`
220
+ 2. Verify deployment: `https://your-project.vercel.app/health`
221
+ 3. Access API docs: `https://your-project.vercel.app/docs`
222
+
223
+ ### Option 2: One-Click Deploy Button
224
+
225
+ [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vezlo/assistant-server&integration-ids=oac_f2GcBt8U4FhiVJ4qWv5PYMEZ)
165
226
 
166
227
  This will:
167
228
  - Fork the repository to your GitHub
168
229
  - Create a Vercel project
169
- - Prompt for required environment variables
230
+ - Require marketplace integration setup
170
231
  - Deploy automatically
171
232
 
172
- ### Manual Vercel Deploy
233
+ ### Option 3: Manual Vercel Deploy
173
234
 
174
235
  ```bash
175
236
  # Install Vercel CLI
@@ -183,9 +244,9 @@ vercel
183
244
 
184
245
  ### Prerequisites for Vercel
185
246
 
186
- 1. **Setup Database First**: Run `vezlo-setup` locally or execute `database-schema.sql` in Supabase
187
- 2. **Get Credentials**: Collect Supabase and OpenAI credentials
188
- 3. **Configure Environment Variables** in Vercel project settings
247
+ 1. Supabase project (URL, Service Role key, DB host/port/name/user/password)
248
+ 2. OpenAI API key
249
+ 3. If not using the Marketplace, add environment variables in Vercel project settings
189
250
 
190
251
  See [docs/VERCEL_DEPLOYMENT.md](docs/VERCEL_DEPLOYMENT.md) for detailed deployment guide.
191
252
 
@@ -196,7 +257,6 @@ Edit `.env` file with your credentials:
196
257
  ```bash
197
258
  # REQUIRED - Supabase Configuration
198
259
  SUPABASE_URL=https://your-project-id.supabase.co
199
- SUPABASE_ANON_KEY=your-anon-key
200
260
  SUPABASE_SERVICE_KEY=your-service-role-key
201
261
 
202
262
  # REQUIRED - Database Configuration for Knex.js Migrations
@@ -215,6 +275,11 @@ AI_MAX_TOKENS=1000
215
275
  # REQUIRED - Database Migration Security
216
276
  MIGRATION_SECRET_KEY=your-secure-migration-key-here
217
277
 
278
+ # REQUIRED - Authentication
279
+ JWT_SECRET=your-super-secret-jwt-key-here-change-this-in-production
280
+ DEFAULT_ADMIN_EMAIL=admin@vezlo.org
281
+ DEFAULT_ADMIN_PASSWORD=admin123
282
+
218
283
  # OPTIONAL - Server Configuration
219
284
  PORT=3000
220
285
  NODE_ENV=production
@@ -223,6 +288,9 @@ LOG_LEVEL=info
223
288
  # OPTIONAL - CORS Configuration
224
289
  CORS_ORIGINS=http://localhost:3000,http://localhost:5173
225
290
 
291
+ # OPTIONAL - Swagger Base URL
292
+ BASE_URL=http://localhost:3000
293
+
226
294
  # OPTIONAL - Rate Limiting
227
295
  RATE_LIMIT_WINDOW=60000
228
296
  RATE_LIMIT_MAX=100
@@ -231,12 +299,6 @@ RATE_LIMIT_MAX=100
231
299
  ORGANIZATION_NAME=Vezlo
232
300
  ASSISTANT_NAME=Vezlo Assistant
233
301
 
234
- # OPTIONAL - Feature Flags
235
- ENABLE_CACHE=true
236
- ENABLE_VOICE=true
237
- ENABLE_GITHUB_SYNC=true
238
- ENABLE_HUMAN_HANDOFF=true
239
-
240
302
  # OPTIONAL - Knowledge Base
241
303
  CHUNK_SIZE=1000
242
304
  CHUNK_OVERLAP=200
@@ -247,20 +309,36 @@ CHUNK_OVERLAP=200
247
309
  The package provides these command-line tools:
248
310
 
249
311
  ### vezlo-setup
250
- **Interactive setup wizard** that guides you through the complete configuration process. This CLI tool provides the same functionality as the web-based setup wizard but runs in your terminal.
312
+ Interactive setup wizard that guides you through configuration.
251
313
 
252
314
  ```bash
253
315
  vezlo-setup
254
316
  ```
255
317
 
318
+ ### vezlo-seed-default
319
+ Creates default admin user and company.
320
+
321
+ ```bash
322
+ vezlo-seed-default
323
+ ```
324
+
325
+ ### vezlo-generate-key
326
+ Generates API key for the default admin's company. The API key is used by src-to-kb library.
327
+
328
+ ```bash
329
+ vezlo-generate-key
330
+ ```
331
+
256
332
  ### vezlo-validate
257
333
  Validates database connection and verifies all tables exist.
334
+
258
335
  ```bash
259
336
  vezlo-validate
260
337
  ```
261
338
 
262
339
  ### vezlo-server
263
340
  Starts the API server.
341
+
264
342
  ```bash
265
343
  vezlo-server
266
344
  ```
@@ -393,19 +471,32 @@ curl -X POST /api/messages/msg456/generate \
393
471
 
394
472
  ## 🗄️ Database Setup
395
473
 
396
- Run the SQL schema in your Supabase SQL Editor:
474
+ ### Option A: Run Migrations (Recommended)
475
+
476
+ Use the built‑in migration endpoints to create/upgrade tables:
477
+
478
+ ```bash
479
+ # Run pending migrations
480
+ curl "http://localhost:3000/api/migrate?key=your-migration-secret-key"
481
+
482
+ # Check migration status
483
+ curl "http://localhost:3000/api/migrate/status?key=your-migration-secret-key"
484
+ ```
485
+
486
+ These endpoints execute Knex migrations and keep schema versioned.
487
+
488
+ ### Option B: Manual SQL (Fallback)
489
+
490
+ If you prefer manual setup, run the SQL schema in Supabase SQL Editor:
397
491
 
398
492
  ```bash
399
- # Copy the database schema file
400
- cp database-schema.sql /path/to/your/supabase/sql-editor
493
+ # View the schema SQL locally
494
+ cat database-schema.sql
495
+
496
+ # Copy into Supabase Dashboard → SQL Editor and execute
401
497
  ```
402
498
 
403
- The `database-schema.sql` file contains all necessary tables and functions:
404
- - **conversations** - Chat conversation management
405
- - **messages** - Individual messages within conversations
406
- - **message_feedback** - User feedback on messages
407
- - **knowledge_items** - Knowledge base items with vector embeddings
408
- - **match_knowledge_items()** - Vector similarity search function
499
+ The `database-schema.sql` contains all required tables and functions.
409
500
 
410
501
  ## 🐳 Docker Commands
411
502
 
@@ -478,8 +569,11 @@ npm install
478
569
  # Build TypeScript
479
570
  npm run build
480
571
 
481
- # Start development server
482
- npm run dev
572
+ # Start server (Node)
573
+ npm start
574
+
575
+ # Or start via CLI wrapper
576
+ npx vezlo-server
483
577
 
484
578
  # Run tests
485
579
  npm test
@@ -518,8 +612,11 @@ Ensure all required environment variables are set:
518
612
  - `SUPABASE_DB_HOST`, `SUPABASE_DB_PASSWORD` (required for migrations)
519
613
  - `OPENAI_API_KEY` (required)
520
614
  - `MIGRATION_SECRET_KEY` (required for migration endpoints)
615
+ - `JWT_SECRET` (required for authentication)
616
+ - `DEFAULT_ADMIN_EMAIL` and `DEFAULT_ADMIN_PASSWORD` (required for initial setup)
521
617
  - `NODE_ENV=production`
522
618
  - `CORS_ORIGINS` (set to your domain)
619
+ - `BASE_URL` (optional, for custom Swagger server URL)
523
620
 
524
621
  ### Docker Production
525
622
  ```bash
@@ -603,4 +700,4 @@ This project is dual-licensed:
603
700
 
604
701
  ---
605
702
 
606
- **Status**: ✅ Production Ready | **Version**: 1.3.0 | **Node.js**: 20+ | **TypeScript**: 5+
703
+ **Status**: ✅ Production Ready | **Version**: 2.0.0 | **Node.js**: 20+ | **TypeScript**: 5+
@@ -9,7 +9,7 @@ const path = require('path');
9
9
  const fs = require('fs');
10
10
 
11
11
  // Check if server is built
12
- const serverPath = path.join(__dirname, '..', 'dist', 'server.js');
12
+ const serverPath = path.join(__dirname, '..', 'dist', 'src', 'server.js');
13
13
 
14
14
  if (!fs.existsSync(serverPath)) {
15
15
  console.error('❌ Error: Server not built. Please run "npm run build" first.');
@@ -1,49 +1,128 @@
1
- -- Vezlo AI Assistant - Modern Database Schema
2
- -- Finalized schema with conversation-based chat and unified knowledge base
1
+ -- Vezlo AI Assistant - Database Schema
2
+ -- Simplified schema dump with all tables, indexes, and constraints
3
3
  -- Run this in your Supabase SQL Editor
4
- -- All tables prefixed with 'vezlo_' to avoid conflicts with existing user tables
5
4
 
6
5
  -- Enable required extensions
7
6
  CREATE EXTENSION IF NOT EXISTS vector;
8
7
 
9
8
  -- ============================================================================
10
- -- CONVERSATIONS & MESSAGES SCHEMA (Modern 2-API Flow)
9
+ -- KNEX MIGRATION TRACKING TABLES
10
+ -- ============================================================================
11
+
12
+ -- Knex.js migration tracking table
13
+ CREATE TABLE IF NOT EXISTS knex_migrations (
14
+ id SERIAL PRIMARY KEY,
15
+ name VARCHAR(255) NOT NULL,
16
+ batch INTEGER NOT NULL,
17
+ migration_time TIMESTAMPTZ DEFAULT NOW()
18
+ );
19
+
20
+ -- Knex.js migration lock table
21
+ CREATE TABLE IF NOT EXISTS knex_migrations_lock (
22
+ index INTEGER PRIMARY KEY,
23
+ is_locked INTEGER
24
+ );
25
+
26
+ -- Insert initial migration entries (marks migrations as already run)
27
+ -- This ensures Knex knows the schema was created manually
28
+ -- Only insert if they don't already exist
29
+ INSERT INTO knex_migrations (name, batch, migration_time)
30
+ SELECT '001_initial_schema.ts', 1, NOW()
31
+ WHERE NOT EXISTS (SELECT 1 FROM knex_migrations WHERE name = '001_initial_schema.ts');
32
+
33
+ INSERT INTO knex_migrations (name, batch, migration_time)
34
+ SELECT '002_multitenancy_schema.ts', 1, NOW()
35
+ WHERE NOT EXISTS (SELECT 1 FROM knex_migrations WHERE name = '002_multitenancy_schema.ts');
36
+
37
+ -- Set migration lock to unlocked (0 = unlocked, 1 = locked)
38
+ INSERT INTO knex_migrations_lock (index, is_locked)
39
+ VALUES (1, 0)
40
+ ON CONFLICT (index) DO UPDATE SET is_locked = 0;
41
+
42
+ -- ============================================================================
43
+ -- USERS & COMPANIES SCHEMA (Multi-tenancy)
44
+ -- ============================================================================
45
+
46
+ CREATE TABLE IF NOT EXISTS vezlo_users (
47
+ id BIGSERIAL PRIMARY KEY,
48
+ uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
49
+ email TEXT UNIQUE NOT NULL,
50
+ name TEXT NOT NULL,
51
+ password_hash TEXT NOT NULL,
52
+ user_type TEXT DEFAULT 'internal', -- internal, external, admin
53
+ token_updated_at TIMESTAMPTZ DEFAULT NOW(),
54
+ created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
55
+ updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
56
+ );
57
+
58
+ CREATE TABLE IF NOT EXISTS vezlo_companies (
59
+ id BIGSERIAL PRIMARY KEY,
60
+ uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
61
+ name TEXT NOT NULL,
62
+ domain TEXT UNIQUE,
63
+ created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
64
+ updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
65
+ );
66
+
67
+ CREATE TABLE IF NOT EXISTS vezlo_user_company_profiles (
68
+ id BIGSERIAL PRIMARY KEY,
69
+ uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
70
+ user_id BIGINT NOT NULL REFERENCES vezlo_users(id) ON DELETE CASCADE,
71
+ company_id BIGINT NOT NULL REFERENCES vezlo_companies(id) ON DELETE CASCADE,
72
+ role TEXT DEFAULT 'user', -- admin, user, viewer
73
+ status TEXT DEFAULT 'active', -- active, inactive
74
+ created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
75
+ updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
76
+ UNIQUE(user_id, company_id)
77
+ );
78
+
79
+ CREATE TABLE IF NOT EXISTS vezlo_api_keys (
80
+ id BIGSERIAL PRIMARY KEY,
81
+ uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
82
+ company_id BIGINT NOT NULL REFERENCES vezlo_companies(id) ON DELETE CASCADE,
83
+ name TEXT NOT NULL,
84
+ key_hash TEXT NOT NULL,
85
+ expires_at TIMESTAMPTZ,
86
+ created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
87
+ updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
88
+ );
89
+
90
+ -- ============================================================================
91
+ -- CONVERSATIONS & MESSAGES SCHEMA
11
92
  -- ============================================================================
12
93
 
13
- -- Conversations table (renamed from chat_sessions)
14
94
  CREATE TABLE IF NOT EXISTS vezlo_conversations (
15
95
  id BIGSERIAL PRIMARY KEY,
16
96
  uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
17
- company_id BIGINT, -- Multi-tenancy support
18
- creator_id BIGINT NOT NULL, -- User who created conversation
97
+ company_id BIGINT, -- Foreign key added in migration 002
98
+ creator_id BIGINT NOT NULL,
19
99
  title TEXT NOT NULL,
20
100
  message_count INTEGER DEFAULT 0,
21
- created_at TIMESTAMPTZ DEFAULT NOW(),
22
- updated_at TIMESTAMPTZ DEFAULT NOW(),
23
- deleted_at TIMESTAMPTZ -- Soft delete
101
+ created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
102
+ updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
103
+ deleted_at TIMESTAMPTZ -- Soft delete
24
104
  );
25
105
 
26
- -- Messages table (supports parent-child relationships for regeneration)
27
106
  CREATE TABLE IF NOT EXISTS vezlo_messages (
28
107
  id BIGSERIAL PRIMARY KEY,
29
108
  uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
30
109
  conversation_id BIGINT NOT NULL REFERENCES vezlo_conversations(id) ON DELETE CASCADE,
31
110
  parent_message_id BIGINT REFERENCES vezlo_messages(id), -- For regeneration chains
32
- type TEXT NOT NULL, -- user, assistant, system
111
+ type TEXT NOT NULL, -- user, assistant, system
33
112
  content TEXT NOT NULL,
34
- status TEXT DEFAULT 'completed', -- generating, completed, stopped, failed
35
- metadata JSONB DEFAULT '{}', -- For tool_calls, tool_results, etc.
36
- created_at TIMESTAMPTZ DEFAULT NOW(),
37
- updated_at TIMESTAMPTZ DEFAULT NOW()
113
+ status TEXT DEFAULT 'completed', -- generating, completed, stopped, failed
114
+ metadata JSONB DEFAULT '{}', -- For tool_calls, tool_results, etc.
115
+ created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
116
+ updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
38
117
  );
39
118
 
40
- -- Message feedback table
41
119
  CREATE TABLE IF NOT EXISTS vezlo_message_feedback (
42
120
  id BIGSERIAL PRIMARY KEY,
43
121
  uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
44
122
  message_id BIGINT NOT NULL REFERENCES vezlo_messages(id) ON DELETE CASCADE,
45
- user_id BIGINT NOT NULL,
46
- rating TEXT NOT NULL, -- positive, negative
123
+ user_id BIGINT NOT NULL, -- Foreign key added in migration 002
124
+ company_id BIGINT, -- Added in migration 002 with foreign key
125
+ rating TEXT NOT NULL, -- positive, negative
47
126
  category TEXT,
48
127
  comment TEXT,
49
128
  suggested_improvement TEXT,
@@ -51,34 +130,98 @@ CREATE TABLE IF NOT EXISTS vezlo_message_feedback (
51
130
  );
52
131
 
53
132
  -- ============================================================================
54
- -- KNOWLEDGE BASE SCHEMA (Unified Single Table)
133
+ -- KNOWLEDGE BASE SCHEMA
55
134
  -- ============================================================================
56
135
 
57
- -- Knowledge items table (folders, documents, files, URLs - everything)
58
136
  CREATE TABLE IF NOT EXISTS vezlo_knowledge_items (
59
137
  id BIGSERIAL PRIMARY KEY,
60
138
  uuid UUID DEFAULT gen_random_uuid() UNIQUE NOT NULL,
61
139
  parent_id BIGINT REFERENCES vezlo_knowledge_items(id), -- Hierarchical structure
62
- company_id BIGINT, -- Multi-tenancy support
140
+ company_id BIGINT, -- Foreign key added in migration 002
63
141
  title TEXT NOT NULL,
64
142
  description TEXT,
65
- type TEXT NOT NULL, -- folder, document, file, url, url_directory
66
- content TEXT, -- For document type
67
- file_url TEXT, -- For file/url types
68
- file_size BIGINT, -- File size in bytes
69
- file_type TEXT, -- MIME type for files
70
- metadata JSONB DEFAULT '{}', -- Flexible metadata storage
71
- embedding vector(1536), -- OpenAI embeddings for search
72
- processed_at TIMESTAMPTZ, -- When embedding was generated
143
+ type TEXT NOT NULL, -- folder, document, file, url, url_directory
144
+ content TEXT, -- For document type
145
+ file_url TEXT, -- For file/url types
146
+ file_size BIGINT, -- File size in bytes
147
+ file_type TEXT, -- MIME type for files
148
+ metadata JSONB DEFAULT '{}', -- Flexible metadata storage
149
+ embedding vector(1536), -- OpenAI embeddings for search
150
+ processed_at TIMESTAMPTZ, -- When embedding was generated
73
151
  created_by BIGINT NOT NULL,
74
- created_at TIMESTAMPTZ DEFAULT NOW(),
75
- updated_at TIMESTAMPTZ DEFAULT NOW()
152
+ created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
153
+ updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
76
154
  );
77
155
 
156
+ -- ============================================================================
157
+ -- ADD FOREIGN KEY CONSTRAINTS (Matching Migration 002)
158
+ -- These constraints use explicit names matching Knex migration naming convention
159
+ -- for proper rollback compatibility: {table}_{column}_foreign
160
+ -- ============================================================================
161
+
162
+ -- Add foreign keys to vezlo_conversations (added in migration 002)
163
+ DO $$
164
+ BEGIN
165
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'vezlo_conversations_company_id_foreign') THEN
166
+ ALTER TABLE vezlo_conversations
167
+ ADD CONSTRAINT vezlo_conversations_company_id_foreign
168
+ FOREIGN KEY (company_id) REFERENCES vezlo_companies(id) ON DELETE CASCADE;
169
+ END IF;
170
+ END $$;
171
+
172
+ -- Add foreign keys to vezlo_knowledge_items (added in migration 002)
173
+ DO $$
174
+ BEGIN
175
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'vezlo_knowledge_items_company_id_foreign') THEN
176
+ ALTER TABLE vezlo_knowledge_items
177
+ ADD CONSTRAINT vezlo_knowledge_items_company_id_foreign
178
+ FOREIGN KEY (company_id) REFERENCES vezlo_companies(id) ON DELETE CASCADE;
179
+ END IF;
180
+ END $$;
181
+
182
+ -- Add foreign keys to vezlo_message_feedback (added in migration 002)
183
+ DO $$
184
+ BEGIN
185
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'vezlo_message_feedback_user_id_foreign') THEN
186
+ ALTER TABLE vezlo_message_feedback
187
+ ADD CONSTRAINT vezlo_message_feedback_user_id_foreign
188
+ FOREIGN KEY (user_id) REFERENCES vezlo_users(id) ON DELETE CASCADE;
189
+ END IF;
190
+
191
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'vezlo_message_feedback_company_id_foreign') THEN
192
+ ALTER TABLE vezlo_message_feedback
193
+ ADD CONSTRAINT vezlo_message_feedback_company_id_foreign
194
+ FOREIGN KEY (company_id) REFERENCES vezlo_companies(id) ON DELETE CASCADE;
195
+ END IF;
196
+ END $$;
197
+
78
198
  -- ============================================================================
79
199
  -- INDEXES FOR PERFORMANCE
80
200
  -- ============================================================================
81
201
 
202
+ -- Users indexes
203
+ CREATE INDEX IF NOT EXISTS idx_vezlo_users_uuid ON vezlo_users(uuid);
204
+ CREATE INDEX IF NOT EXISTS idx_vezlo_users_email ON vezlo_users(email);
205
+ CREATE INDEX IF NOT EXISTS idx_vezlo_users_user_type ON vezlo_users(user_type);
206
+ CREATE INDEX IF NOT EXISTS idx_vezlo_users_token_updated_at ON vezlo_users(token_updated_at);
207
+
208
+ -- Companies indexes
209
+ CREATE INDEX IF NOT EXISTS idx_vezlo_companies_uuid ON vezlo_companies(uuid);
210
+ CREATE INDEX IF NOT EXISTS idx_vezlo_companies_domain ON vezlo_companies(domain);
211
+
212
+ -- User company profiles indexes
213
+ CREATE INDEX IF NOT EXISTS idx_vezlo_user_company_profiles_uuid ON vezlo_user_company_profiles(uuid);
214
+ CREATE INDEX IF NOT EXISTS idx_vezlo_user_company_profiles_user_id ON vezlo_user_company_profiles(user_id);
215
+ CREATE INDEX IF NOT EXISTS idx_vezlo_user_company_profiles_company_id ON vezlo_user_company_profiles(company_id);
216
+ CREATE INDEX IF NOT EXISTS idx_vezlo_user_company_profiles_role ON vezlo_user_company_profiles(role);
217
+ CREATE INDEX IF NOT EXISTS idx_vezlo_user_company_profiles_status ON vezlo_user_company_profiles(status);
218
+
219
+ -- API keys indexes
220
+ CREATE INDEX IF NOT EXISTS idx_vezlo_api_keys_uuid ON vezlo_api_keys(uuid);
221
+ CREATE INDEX IF NOT EXISTS idx_vezlo_api_keys_company_id ON vezlo_api_keys(company_id);
222
+ CREATE INDEX IF NOT EXISTS idx_vezlo_api_keys_key_hash ON vezlo_api_keys(key_hash);
223
+ CREATE INDEX IF NOT EXISTS idx_vezlo_api_keys_expires_at ON vezlo_api_keys(expires_at);
224
+
82
225
  -- Conversations indexes
83
226
  CREATE INDEX IF NOT EXISTS idx_vezlo_conversations_uuid ON vezlo_conversations(uuid);
84
227
  CREATE INDEX IF NOT EXISTS idx_vezlo_conversations_company_id ON vezlo_conversations(company_id);
@@ -98,6 +241,7 @@ CREATE INDEX IF NOT EXISTS idx_vezlo_messages_created_at ON vezlo_messages(creat
98
241
  CREATE INDEX IF NOT EXISTS idx_vezlo_feedback_uuid ON vezlo_message_feedback(uuid);
99
242
  CREATE INDEX IF NOT EXISTS idx_vezlo_feedback_message_id ON vezlo_message_feedback(message_id);
100
243
  CREATE INDEX IF NOT EXISTS idx_vezlo_feedback_user_id ON vezlo_message_feedback(user_id);
244
+ CREATE INDEX IF NOT EXISTS idx_vezlo_feedback_company_id ON vezlo_message_feedback(company_id);
101
245
  CREATE INDEX IF NOT EXISTS idx_vezlo_feedback_rating ON vezlo_message_feedback(rating);
102
246
 
103
247
  -- Knowledge items indexes
@@ -129,12 +273,28 @@ ON vezlo_knowledge_items(file_url) WHERE file_url IS NOT NULL;
129
273
  -- ============================================================================
130
274
 
131
275
  -- Enable RLS on all tables
276
+ ALTER TABLE vezlo_users ENABLE ROW LEVEL SECURITY;
277
+ ALTER TABLE vezlo_companies ENABLE ROW LEVEL SECURITY;
278
+ ALTER TABLE vezlo_user_company_profiles ENABLE ROW LEVEL SECURITY;
279
+ ALTER TABLE vezlo_api_keys ENABLE ROW LEVEL SECURITY;
132
280
  ALTER TABLE vezlo_conversations ENABLE ROW LEVEL SECURITY;
133
281
  ALTER TABLE vezlo_messages ENABLE ROW LEVEL SECURITY;
134
282
  ALTER TABLE vezlo_message_feedback ENABLE ROW LEVEL SECURITY;
135
283
  ALTER TABLE vezlo_knowledge_items ENABLE ROW LEVEL SECURITY;
136
284
 
137
285
  -- Policies for service role access (full access)
286
+ CREATE POLICY "Service role can access all users" ON vezlo_users
287
+ FOR ALL USING (auth.role() = 'service_role');
288
+
289
+ CREATE POLICY "Service role can access all companies" ON vezlo_companies
290
+ FOR ALL USING (auth.role() = 'service_role');
291
+
292
+ CREATE POLICY "Service role can access all user company profiles" ON vezlo_user_company_profiles
293
+ FOR ALL USING (auth.role() = 'service_role');
294
+
295
+ CREATE POLICY "Service role can access all API keys" ON vezlo_api_keys
296
+ FOR ALL USING (auth.role() = 'service_role');
297
+
138
298
  CREATE POLICY "Service role can access all conversations" ON vezlo_conversations
139
299
  FOR ALL USING (auth.role() = 'service_role');
140
300
 
@@ -150,6 +310,6 @@ CREATE POLICY "Service role can access all knowledge items" ON vezlo_knowledge_i
150
310
  -- Example company-based policies (uncomment and modify as needed)
151
311
  -- CREATE POLICY "Users can access their company conversations" ON vezlo_conversations
152
312
  -- FOR ALL USING (company_id = auth.jwt() ->> 'company_id');
153
-
313
+ --
154
314
  -- CREATE POLICY "Users can access their company knowledge" ON vezlo_knowledge_items
155
315
  -- FOR ALL USING (company_id = auth.jwt() ->> 'company_id');
@@ -1 +1 @@
1
- {"version":3,"file":"knexfile.d.ts","sourceRoot":"","sources":["../knexfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAcjC,QAAA,MAAM,MAAM,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;CA4EzC,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"knexfile.d.ts","sourceRoot":"","sources":["../knexfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAejC,QAAA,MAAM,MAAM,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;CAoFzC,CAAC;AAEF,eAAe,MAAM,CAAC"}