feat(#128): add LlmProviderInstance Prisma schema

Added database schema for LLM provider instance configuration to support
multi-provider architecture.

Schema design:
- LlmProviderInstance model with UUID primary key
- Fields: providerType, displayName, userId, config, isDefault, isEnabled
- JSON config field for flexible provider-specific settings
- Nullable userId: NULL = system-level, UUID = user-level
- Foreign key to User with CASCADE delete
- Added llmProviders relation to User model

Indexes:
- user_id: Fast user lookup
- provider_type: Filter by provider
- is_default: Quick default lookup
- is_enabled: Enabled/disabled filtering

Migration: 20260131115600_add_llm_provider_instance
- PostgreSQL table creation with proper types
- Foreign key constraint
- Performance indexes

Prisma client regenerated successfully.
Database migration requires manual deployment when DB is available.

Fixes #128

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 11:57:40 -06:00
parent dc4f6cbb9d
commit 1e35e63444
3 changed files with 175 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
-- CreateTable
CREATE TABLE "llm_provider_instances" (
"id" UUID NOT NULL,
"provider_type" TEXT NOT NULL,
"display_name" TEXT NOT NULL,
"user_id" UUID,
"config" JSONB NOT NULL,
"is_default" BOOLEAN NOT NULL DEFAULT false,
"is_enabled" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMPTZ NOT NULL,
CONSTRAINT "llm_provider_instances_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "llm_provider_instances_user_id_idx" ON "llm_provider_instances"("user_id");
-- CreateIndex
CREATE INDEX "llm_provider_instances_provider_type_idx" ON "llm_provider_instances"("provider_type");
-- CreateIndex
CREATE INDEX "llm_provider_instances_is_default_idx" ON "llm_provider_instances"("is_default");
-- CreateIndex
CREATE INDEX "llm_provider_instances_is_enabled_idx" ON "llm_provider_instances"("is_enabled");
-- AddForeignKey
ALTER TABLE "llm_provider_instances" ADD CONSTRAINT "llm_provider_instances_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -168,6 +168,7 @@ model User {
userLayouts UserLayout[]
userPreference UserPreference?
knowledgeEntryVersions KnowledgeEntryVersion[] @relation("EntryVersionAuthor")
llmProviders LlmProviderInstance[] @relation("UserLlmProviders")
@@map("users")
}
@@ -944,3 +945,28 @@ model Personality {
@@index([workspaceId, isActive])
@@map("personalities")
}
// ============================================
// LLM PROVIDER MODULE
// ============================================
model LlmProviderInstance {
id String @id @default(uuid()) @db.Uuid
providerType String @map("provider_type") // "ollama" | "claude" | "openai"
displayName String @map("display_name")
userId String? @map("user_id") @db.Uuid // NULL = system-level, UUID = user-level
config Json // Provider-specific configuration
isDefault Boolean @default(false) @map("is_default")
isEnabled Boolean @default(true) @map("is_enabled")
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
// Relations
user User? @relation("UserLlmProviders", fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([providerType])
@@index([isDefault])
@@index([isEnabled])
@@map("llm_provider_instances")
}

View File

@@ -0,0 +1,120 @@
# Issue #128: Add LlmProviderInstance Prisma Schema
## Objective
Create database schema for LLM provider instance configuration to support multi-provider LLM backend.
## Approach
### Schema Design
```prisma
model LlmProviderInstance {
id String @id @default(uuid())
providerType String @map("provider_type") // "ollama" | "claude" | "openai"
displayName String @map("display_name")
userId String? @map("user_id") // NULL = system-level, UUID = user-level
config Json // Provider-specific configuration
isDefault Boolean @default(false) @map("is_default")
isEnabled Boolean @default(true) @map("is_enabled")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([providerType])
@@index([isDefault])
@@map("llm_provider_instances")
}
```
### Configuration Patterns
**System-level instances** (user_id = NULL):
- Available to all users
- Managed by admins only
- Example: Shared Ollama server
**User-level instances** (user_id = UUID):
- Private to specific user
- User manages their own API keys
- Example: Personal OpenAI API key
### Config Field Structure
```json
{
"endpoint": "http://localhost:11434",
"timeout": 30000,
"apiKey": "sk-...", // encrypted in production
"organization": "org-...",
"customHeaders": {}
}
```
## Progress
- [x] Read current Prisma schema
- [x] Add LlmProviderInstance model
- [x] Add relation to User model
- [x] Add indexes for performance
- [x] Create migration (20260131115600_add_llm_provider_instance)
- [x] Update Prisma client types (prisma generate)
- [ ] Run migration on dev database (manual step, requires DB connection)
- [ ] Verify migration succeeded (manual step, requires DB connection)
## Testing
- Verify model is accessible via Prisma client
- Verify indexes exist in database
- Verify foreign key constraints work
- Test both system and user-level instances
## Notes
- Using snake_case for database columns (project convention)
- JSON field for flexible provider configs
- Cascade delete when user is deleted
- `isDefault` allows marking one provider as default per user
## Implementation Details
**Model Added:**
- `LlmProviderInstance` with all required fields
- Foreign key relation to `User` model (nullable for system-level instances)
- Added `llmProviders` relation array to User model
**Indexes Created:**
- `user_id` - Fast lookup by user
- `provider_type` - Fast filtering by provider
- `is_default` - Quick default provider lookup
- `is_enabled` - Filter enabled/disabled providers
**Migration File:** `20260131115600_add_llm_provider_instance`
- Creates table with proper PostgreSQL types
- Sets up foreign key constraint with CASCADE delete
- Creates all performance indexes
## Acceptance Criteria Status
- ✅ Migration created successfully
- ✅ Model accessible via Prisma client (prisma generate succeeded)
- ✅ Indexes defined correctly
- ⏸️ Migration not run (requires database connection)
- ⏸️ No data loss risk (new table, no existing data)
## Next Steps
When database is available:
```bash
pnpm --filter @mosaic/api prisma migrate deploy
# OR for development:
pnpm --filter @mosaic/api prisma migrate dev
```