diff --git a/src/components/collaboration/VideoConference.tsx b/src/components/collaboration/VideoConference.tsx index 304abe6e..6cf8d8ae 100644 --- a/src/components/collaboration/VideoConference.tsx +++ b/src/components/collaboration/VideoConference.tsx @@ -73,6 +73,8 @@ export function VideoConference({ hostUserId, }); + const virtualBackground = useVirtualBackground(); + const signalingUrl = websocketUrl || process.env.NEXT_PUBLIC_WEBSOCKET_URL || 'http://localhost:3001'; diff --git a/src/lib/settings/__tests__/integration.test.ts b/src/lib/settings/__tests__/integration.test.ts index bd81274a..6a4086d5 100644 --- a/src/lib/settings/__tests__/integration.test.ts +++ b/src/lib/settings/__tests__/integration.test.ts @@ -514,5 +514,69 @@ describe('Settings System Integration', () => { expect(validation.valid).toBe(true); }); + + // ── Documentation Update Integration ─────────────────────────────────────────── + + describe('Documentation Update Integration', () => { + it('integrates documentation validation with settings workflow', () => { + const settings = createDefaultSettings(); + const validation = SettingsService.validateSettings(settings); + + expect(validation.valid).toBe(true); + + const docValidation = SettingsService.validateDocumentationCompleteness(); + expect(docValidation.valid).toBe(true); + }); + + it('ensures documentation metadata stays in sync with schema', () => { + const metadata = SettingsService.getDocumentationMetadata(); + const settings = createDefaultSettings(); + + expect(metadata.schemaVersion).toBe(settings.version); + expect(Object.keys(metadata.fields)).toEqual(Object.keys(settings)); + }); + + it('generates documentation update recommendations', () => { + const update = SettingsService.generateDocumentationUpdate(); + + expect(update).toHaveProperty('needsUpdate'); + expect(update).toHaveProperty('summary'); + expect(update).toHaveProperty('suggestions'); + + // Verify suggestions are actionable + if (update.needsUpdate) { + update.suggestions.forEach((suggestion) => { + expect(typeof suggestion).toBe('string'); + expect(suggestion.length).toBeGreaterThan(0); + }); + } + }); + + it('validates documentation completeness end-to-end', () => { + const metadata = SettingsService.getDocumentationMetadata(); + const validation = SettingsService.validateDocumentationCompleteness(); + + expect(validation.valid).toBe(true); + expect(metadata.fields).toBeDefined(); + + // All schema fields should be documented + const defaultSettings = createDefaultSettings(); + Object.keys(defaultSettings).forEach((field) => { + expect(metadata.fields[field]).toBeDefined(); + expect(typeof metadata.fields[field]).toBe('string'); + }); + }); + + it('maintains documentation version consistency', () => { + const metadata = SettingsService.getDocumentationMetadata(); + + expect(metadata.version).toBeTruthy(); + expect(metadata.lastUpdated).toBeTruthy(); + expect(metadata.schemaVersion).toBe(SETTINGS_SCHEMA_VERSION); + }); + }); + }); +}); + }); }); }); diff --git a/src/lib/settings/service.ts b/src/lib/settings/service.ts index 9fc0b32b..c3789613 100644 --- a/src/lib/settings/service.ts +++ b/src/lib/settings/service.ts @@ -11,7 +11,7 @@ import { createDefaultSettings, appSettingsSchema, } from './types'; -import { SETTINGS_SCHEMA_VERSION } from './constants'; +import { SETTINGS_SCHEMA_VERSION, SETTINGS_DOCUMENTATION_VERSION } from './constants'; export interface SettingsValidationResult { valid: boolean; @@ -19,6 +19,13 @@ export interface SettingsValidationResult { data?: AppSettings; } +export interface DocumentationMetadata { + version: string; + lastUpdated: string; + schemaVersion: number; + fields: Record; +} + export interface SettingsSyncResult { success: boolean; message: string; @@ -280,6 +287,96 @@ export class SettingsService { return capabilities[permissionMap[key]] || false; } + /** + * Get documentation metadata for current settings implementation + */ + static getDocumentationMetadata(): DocumentationMetadata { + return { + version: SETTINGS_DOCUMENTATION_VERSION, + lastUpdated: '2025-05-30', + schemaVersion: SETTINGS_SCHEMA_VERSION, + fields: { + version: 'Schema version for settings structure', + theme: 'User color scheme preference', + language: 'Interface language (BCP-47 locale)', + notificationsEnabled: 'Master toggle for in-app notifications', + emailNotifications: 'Email notification preferences', + prefetchingEnabled: 'Link prefetching for performance', + reducedMotion: 'Reduced motion for accessibility', + electronicSignatureEnabled: 'Electronic signature feature toggle', + signatureName: 'User full name for signatures', + requireSignatureOnCertificates: 'Signature confirmation for certificates', + virtualBackgroundEnabled: 'Virtual background master toggle', + virtualBackgroundType: 'Type of virtual background effect', + virtualBackgroundImage: 'Custom background image URL', + virtualBackgroundBlur: 'Blur intensity (0-100)', + virtualBackgroundColor: 'Hex color for solid background', + }, + }; + } + + /** + * Validate documentation completeness against current schema + */ + static validateDocumentationCompleteness(): { + valid: boolean; + missingFields: string[]; + outdatedFields: string[]; + } { + const metadata = this.getDocumentationMetadata(); + const defaultSettings = createDefaultSettings(); + const schemaFields = Object.keys(defaultSettings); + const documentedFields = Object.keys(metadata.fields); + + const missingFields = schemaFields.filter((field) => !documentedFields.includes(field)); + const outdatedFields = documentedFields.filter((field) => !schemaFields.includes(field)); + + return { + valid: missingFields.length === 0 && outdatedFields.length === 0, + missingFields, + outdatedFields, + }; + } + + /** + * Generate documentation update summary + */ + static generateDocumentationUpdate(): { + needsUpdate: boolean; + summary: string; + suggestions: string[]; + } { + const validation = this.validateDocumentationCompleteness(); + const metadata = this.getDocumentationMetadata(); + + if (validation.valid) { + return { + needsUpdate: false, + summary: 'Documentation is up-to-date with current schema', + suggestions: [], + }; + } + + const suggestions: string[] = []; + + if (validation.missingFields.length > 0) { + suggestions.push(`Add documentation for missing fields: ${validation.missingFields.join(', ')}`); + } + + if (validation.outdatedFields.length > 0) { + suggestions.push(`Remove documentation for deprecated fields: ${validation.outdatedFields.join(', ')}`); + } + + suggestions.push(`Update documentation version to reflect changes`); + suggestions.push(`Update lastUpdated timestamp in constants`); + + return { + needsUpdate: true, + summary: `Documentation update required. ${validation.missingFields.length} missing fields, ${validation.outdatedFields.length} outdated fields.`, + suggestions, + }; + } + /** * Apply settings migration if needed (for future version changes) */ diff --git a/src/lib/settings/types.ts b/src/lib/settings/types.ts index c55d4d70..54e8771d 100644 --- a/src/lib/settings/types.ts +++ b/src/lib/settings/types.ts @@ -1,5 +1,5 @@ import { z } from 'zod'; -import { SETTINGS_SCHEMA_VERSION } from './constants'; +import { SETTINGS_SCHEMA_VERSION, SETTINGS_DOCUMENTATION_VERSION } from './constants'; /** User-selectable colour scheme. `'system'` follows the OS preference. */ export const themePreferenceSchema = z.enum(['light', 'dark', 'system']);