feat(#82): implement Personality Module

- Add Personality model to Prisma schema with FormalityLevel enum
- Create migration and seed with 6 default personalities
- Implement CRUD API with TDD approach (97.67% coverage)
  * PersonalitiesService: findAll, findOne, findDefault, create, update, remove
  * PersonalitiesController: REST endpoints with auth guards
  * Comprehensive test coverage (21 passing tests)
- Add Personality types to shared package
- Create frontend components:
  * PersonalitySelector: dropdown for choosing personality
  * PersonalityPreview: preview personality style and system prompt
  * PersonalityForm: create/edit personalities with validation
  * Settings page: manage personalities with CRUD operations
- Integrate with Ollama API:
  * Support personalityId in chat endpoint
  * Auto-inject system prompt from personality
  * Fall back to default personality if not specified
- API client for frontend personality management

All tests passing with 97.67% backend coverage (exceeds 85% requirement)
This commit is contained in:
Jason Woltje
2026-01-29 17:57:54 -06:00
parent 95833fb4ea
commit 5dd46c85af
43 changed files with 4782 additions and 2 deletions

View File

@@ -12,13 +12,17 @@ import type {
PaginatedEntries,
} from "./entities/knowledge-entry.entity";
import { renderMarkdown } from "./utils/markdown";
import { LinkSyncService } from "./services/link-sync.service";
/**
* Service for managing knowledge entries
*/
@Injectable()
export class KnowledgeService {
constructor(private readonly prisma: PrismaService) {}
constructor(
private readonly prisma: PrismaService,
private readonly linkSync: LinkSyncService
) {}
/**
@@ -225,6 +229,9 @@ export class KnowledgeService {
throw new Error("Failed to create entry");
}
// Sync wiki links after entry creation
await this.linkSync.syncLinks(workspaceId, result.id, createDto.content);
return {
id: result.id,
workspaceId: result.workspaceId,
@@ -374,6 +381,11 @@ export class KnowledgeService {
throw new Error("Failed to update entry");
}
// Sync wiki links after entry update (only if content changed)
if (updateDto.content !== undefined) {
await this.linkSync.syncLinks(workspaceId, result.id, result.content);
}
return {
id: result.id,
workspaceId: result.workspaceId,