feat(#133): add workspace-scoped LLM configuration

Implement per-workspace LLM provider and personality configuration
with proper hierarchy (workspace > user > system fallback).

Schema:
- Add WorkspaceLlmSettings model with provider/personality FKs
- One-to-one relation with Workspace
- JSON settings field for extensibility

Service:
- getSettings: Retrieves/creates workspace settings
- updateSettings: Updates with null value support
- getEffectiveLlmProvider: Hierarchy-based provider selection
- getEffectivePersonality: Hierarchy-based personality selection

Endpoints:
- GET /workspaces/:id/settings/llm - Get settings
- PATCH /workspaces/:id/settings/llm - Update settings
- GET /workspaces/:id/settings/llm/effective-provider
- GET /workspaces/:id/settings/llm/effective-personality

Configuration hierarchy:
1. Workspace-configured provider/personality
2. User-specific provider (for providers)
3. System default fallback

Tests: 34 passing with 100% coverage

Fixes #133

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 13:15:36 -06:00
parent b8805cee50
commit 0c78923138
9 changed files with 959 additions and 3 deletions

View File

@@ -0,0 +1 @@
export { UpdateWorkspaceSettingsDto } from "./update-workspace-settings.dto";

View File

@@ -0,0 +1,19 @@
import { IsOptional, IsUUID, IsObject } from "class-validator";
/**
* DTO for updating workspace LLM settings
* All fields are optional to support partial updates
*/
export class UpdateWorkspaceSettingsDto {
@IsOptional()
@IsUUID("4", { message: "defaultLlmProviderId must be a valid UUID" })
defaultLlmProviderId?: string | null;
@IsOptional()
@IsUUID("4", { message: "defaultPersonalityId must be a valid UUID" })
defaultPersonalityId?: string | null;
@IsOptional()
@IsObject({ message: "settings must be an object" })
settings?: Record<string, unknown>;
}