Skip to main content
Glama
database-schema-enhancer.js15.7 kB
// Database Schema Enhancement for Character Trait Storage // Enhances Notion database with comprehensive character consistency fields export class DatabaseSchemaEnhancer { constructor(notionClient) { this.notion = notionClient; this.characterTraitFields = this.defineCharacterTraitFields(); } // Define comprehensive character trait fields for Notion database defineCharacterTraitFields() { return { // Physical Characteristics physicalTraits: { 'Character Size': { type: 'select', options: ['tiny', 'small', 'medium', 'large', 'giant'], description: 'Puppet size category with specific measurements' }, 'Construction Material': { type: 'select', options: ['felt', 'foam', 'fur', 'fleece', 'mixed_materials'], description: 'Primary puppet construction material' }, 'Head Shape': { type: 'select', options: ['round', 'oval', 'angular', 'elongated', 'wide'], description: 'Basic head shape geometry' }, 'Eye Type': { type: 'select', options: ['button', 'plastic', 'fabric', 'ping_pong', 'custom'], description: 'Eye construction type' }, 'Eye Color': { type: 'rich_text', description: 'Specific eye color for consistency' }, 'Mouth Type': { type: 'select', options: ['basic_opening', 'articulated_jaw', 'simple_slit', 'complex_mechanical'], description: 'Mouth mechanism type' }, 'Hair/Fur Type': { type: 'select', options: ['synthetic_hair', 'wool', 'fur_fabric', 'yarn', 'feathers', 'bald'], description: 'Hair or fur material type' }, 'Hand Type': { type: 'select', options: ['simple_mittens', 'articulated_fingers', 'rod_controlled', 'glove_style'], description: 'Hand construction and control method' }, 'Primary Color': { type: 'rich_text', description: 'Main character color for consistency' }, 'Secondary Color': { type: 'rich_text', description: 'Secondary character color' }, 'Special Markings': { type: 'rich_text', description: 'Unique markings, scars, patterns, or distinctive features' }, 'Clothing Description': { type: 'rich_text', description: 'Standard clothing or accessories' } }, // Movement and Mechanics movementTraits: { 'Eye Movement': { type: 'select', options: ['fixed_position', 'limited_side_to_side', 'full_mechanical', 'blink_capable'], description: 'Eye movement capabilities' }, 'Mouth Movement': { type: 'select', options: ['simple_open_close', 'jaw_articulation', 'tongue_visible', 'teeth_visible'], description: 'Mouth movement mechanics' }, 'Head Movement': { type: 'select', options: ['basic_turn', 'full_rotation', 'tilt_capable', 'nod_shake'], description: 'Head movement range' }, 'Body Movement': { type: 'select', options: ['static_pose', 'arm_articulation', 'torso_bend', 'full_puppeteer_control'], description: 'Body movement capabilities' }, 'Hand Movement': { type: 'select', options: ['basic_positioning', 'finger_articulation', 'grip_capable', 'gesture_specific'], description: 'Hand movement and manipulation' }, 'Movement Style': { type: 'select', options: ['bouncy_muppet', 'smooth_gliding', 'jerky_mechanical', 'flowing_graceful'], description: 'Overall movement personality' } }, // Character Personality and Behavior personalityTraits: { 'Energy Level': { type: 'select', options: ['low_energy', 'moderate', 'high_energy', 'hyperactive'], description: 'Character energy and activity level' }, 'Character Archetype': { type: 'select', options: ['hero', 'comic_relief', 'wise_mentor', 'villain', 'innocent', 'quirky'], description: 'Basic character role and archetype' }, 'Voice Match': { type: 'select', options: ['high_pitched', 'deep_resonant', 'raspy_textured', 'smooth_melodic'], description: 'Voice characteristics for audio matching' }, 'Signature Gestures': { type: 'rich_text', description: 'Unique gestures or movements specific to character' }, 'Behavioral Quirks': { type: 'rich_text', description: 'Unique behavioral traits and mannerisms' } }, // Production and Technical productionTraits: { 'Scale Reference Object': { type: 'select', options: ['coin', 'hand', 'smartphone', 'book', 'mug', 'ruler', 'doorframe', 'table', 'chair'], description: 'Standard reference object for scale consistency' }, 'Lighting Setup': { type: 'select', options: ['studio_standard', 'dramatic_side', 'soft_diffused', 'high_contrast', 'theatrical'], description: 'Preferred lighting setup for character' }, 'Camera Angle Preference': { type: 'select', options: ['straight_on', 'slight_low', 'slight_high', 'dynamic_angle'], description: 'Best camera angle for character presentation' }, 'Background Preference': { type: 'select', options: ['solid_black', 'gradient_black', 'studio_backdrop', 'minimal_props'], description: 'Background setup preference' } }, // Consistency and Quality Control qualityControl: { 'Consistency Score': { type: 'number', description: 'Overall consistency rating (1-10) across productions' }, 'Last Updated': { type: 'date', description: 'Last time character traits were updated' }, 'Generation Count': { type: 'number', description: 'Number of times character has been generated' }, 'Quality Issues': { type: 'multi_select', options: ['scale_inconsistency', 'color_variation', 'feature_drift', 'construction_errors', 'lighting_mismatch'], description: 'Tracked quality issues for improvement' }, 'Approved Variations': { type: 'rich_text', description: 'Approved variations from base character design' } } }; } // Generate character traits object from Notion page properties extractCharacterTraits(notionPage) { const properties = notionPage.properties; const traits = {}; // Extract basic info traits.name = this.extractText(properties['Character Name']); traits.description = this.extractText(properties['Character Bio']); // Extract physical traits traits.size = this.extractSelect(properties['Character Size']); traits.construction = this.extractSelect(properties['Construction Material']); traits.headShape = this.extractSelect(properties['Head Shape']); traits.eyeType = this.extractSelect(properties['Eye Type']); traits.eyeColor = this.extractText(properties['Eye Color']); traits.mouthType = this.extractSelect(properties['Mouth Type']); traits.hairFur = this.extractSelect(properties['Hair/Fur Type']); traits.handType = this.extractSelect(properties['Hand Type']); traits.primaryColor = this.extractText(properties['Primary Color']); traits.secondaryColor = this.extractText(properties['Secondary Color']); traits.specialMarkings = this.extractText(properties['Special Markings']); traits.clothing = this.extractText(properties['Clothing Description']); // Extract movement traits traits.eyeMovement = this.extractSelect(properties['Eye Movement']); traits.mouthMovement = this.extractSelect(properties['Mouth Movement']); traits.headMovement = this.extractSelect(properties['Head Movement']); traits.bodyMovement = this.extractSelect(properties['Body Movement']); traits.handMovement = this.extractSelect(properties['Hand Movement']); traits.movementStyle = this.extractSelect(properties['Movement Style']); // Extract personality traits traits.energyLevel = this.extractSelect(properties['Energy Level']); traits.archetype = this.extractSelect(properties['Character Archetype']); traits.voiceMatch = this.extractSelect(properties['Voice Match']); traits.signatureGestures = this.extractText(properties['Signature Gestures']); traits.behavioralQuirks = this.extractText(properties['Behavioral Quirks']); // Extract production traits traits.scaleReference = this.extractSelect(properties['Scale Reference Object']); traits.lightingSetup = this.extractSelect(properties['Lighting Setup']); traits.cameraAngle = this.extractSelect(properties['Camera Angle Preference']); traits.backgroundPreference = this.extractSelect(properties['Background Preference']); return traits; } // Helper methods for extracting different property types extractText(property) { if (!property) return ''; if (property.rich_text && property.rich_text[0]) { return property.rich_text[0].text.content; } if (property.title && property.title[0]) { return property.title[0].text.content; } return ''; } extractSelect(property) { if (!property || !property.select) return ''; return property.select.name; } extractMultiSelect(property) { if (!property || !property.multi_select) return []; return property.multi_select.map(item => item.name); } extractNumber(property) { if (!property || property.number === null) return 0; return property.number; } // Create character with comprehensive traits async createCharacterWithTraits(characterData, traits) { const properties = { // Basic character info 'Character Name': { title: [{ text: { content: characterData.name } }] }, 'Character Bio': { rich_text: [{ text: { content: characterData.description } }] }, 'Character Type': { select: { name: characterData.characterType || 'Main Character' } }, 'Status': { select: { name: 'In Development' } }, // Physical traits 'Character Size': { select: { name: traits.size || 'medium' } }, 'Construction Material': { select: { name: traits.construction || 'felt' } }, 'Head Shape': { select: { name: traits.headShape || 'round' } }, 'Eye Type': { select: { name: traits.eyeType || 'button' } }, 'Eye Color': { rich_text: [{ text: { content: traits.eyeColor || 'brown' } }] }, 'Mouth Type': { select: { name: traits.mouthType || 'basic_opening' } }, 'Hair/Fur Type': { select: { name: traits.hairFur || 'synthetic_hair' } }, 'Hand Type': { select: { name: traits.handType || 'simple_mittens' } }, 'Primary Color': { rich_text: [{ text: { content: traits.primaryColor || 'brown' } }] }, 'Secondary Color': { rich_text: [{ text: { content: traits.secondaryColor || 'white' } }] }, // Movement traits 'Movement Style': { select: { name: traits.movementStyle || 'bouncy_muppet' } }, 'Eye Movement': { select: { name: traits.eyeMovement || 'fixed_position' } }, 'Mouth Movement': { select: { name: traits.mouthMovement || 'simple_open_close' } }, // Personality traits 'Energy Level': { select: { name: traits.energyLevel || 'moderate' } }, 'Character Archetype': { select: { name: traits.archetype || 'hero' } }, // Production traits 'Scale Reference Object': { select: { name: traits.scaleReference || 'hand' } }, 'Lighting Setup': { select: { name: traits.lightingSetup || 'studio_standard' } }, 'Background Preference': { select: { name: traits.backgroundPreference || 'solid_black' } }, // Quality control 'Generation Count': { number: 0 }, 'Last Updated': { date: { start: new Date().toISOString().split('T')[0] } } }; // Add optional fields if provided if (traits.specialMarkings) { properties['Special Markings'] = { rich_text: [{ text: { content: traits.specialMarkings } }] }; } if (traits.clothing) { properties['Clothing Description'] = { rich_text: [{ text: { content: traits.clothing } }] }; } if (traits.signatureGestures) { properties['Signature Gestures'] = { rich_text: [{ text: { content: traits.signatureGestures } }] }; } if (traits.behavioralQuirks) { properties['Behavioral Quirks'] = { rich_text: [{ text: { content: traits.behavioralQuirks } }] }; } return properties; } // Update character generation count and consistency tracking async updateCharacterUsage(characterId, qualityScore = null) { const currentPage = await this.notion.pages.retrieve({ page_id: characterId }); const currentCount = this.extractNumber(currentPage.properties['Generation Count']); const updateData = { 'Generation Count': { number: currentCount + 1 }, 'Last Updated': { date: { start: new Date().toISOString().split('T')[0] } } }; if (qualityScore !== null) { updateData['Consistency Score'] = { number: qualityScore }; } await this.notion.pages.update({ page_id: characterId, properties: updateData }); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bermingham85/mcp-puppet-pipeline'

If you have feedback or need assistance with the MCP directory API, please join our Discord server