UNPKG

@mindmakr/gs-websdk

Version:

Web SDK for Guru SaaS System - Complete JavaScript/TypeScript SDK for building applications with dynamic schema management

1,139 lines (1,021 loc) 27.1 kB
# Schema Management Guide This guide provides comprehensive information about working with dynamic schemas in the Guru SaaS system, including schema structure, field types, validation, composition, and best practices. ## Table of Contents - [Understanding Schema Structure](#understanding-schema-structure) - [Field Types Reference](#field-types-reference) - [Schema Validation](#schema-validation) - [Template Composition](#template-composition) - [Path-Based Organization](#path-based-organization) - [Versioning & Lifecycle](#versioning--lifecycle) - [AI-Powered Enhancement](#ai-powered-enhancement) - [Translation & Internationalization](#translation--internationalization) - [Best Practices](#best-practices) ## Understanding Schema Structure ### Basic JSON Schema Format Guru SaaS uses an extended JSON Schema format with additional UI and layout properties: ```json { "type": "object", "title": "Customer Profile", "description": "Comprehensive customer information form", "properties": { "firstName": { "type": "string", "title": "First Name", "description": "Customer's first name", "minLength": 1, "maxLength": 50 }, "email": { "type": "string", "format": "email", "title": "Email Address", "description": "Primary contact email" }, "age": { "type": "integer", "title": "Age", "minimum": 18, "maximum": 120 }, "preferences": { "type": "object", "title": "Preferences", "properties": { "newsletter": { "type": "boolean", "title": "Subscribe to Newsletter", "default": false }, "contactMethod": { "type": "string", "title": "Preferred Contact Method", "enum": ["email", "phone", "sms"], "enumNames": ["Email", "Phone", "SMS"], "default": "email" } } } }, "required": ["firstName", "email"], "x-field-order": ["firstName", "email", "age", "preferences"] } ``` ### Extended Properties Beyond standard JSON Schema, Guru SaaS supports additional properties: #### UI Properties ```json { "fieldName": { "type": "string", "title": "Field Title", "ui:widget": "textarea", "ui:placeholder": "Enter your text here", "ui:help": "This field accepts markdown formatting", "ui:layout": { "width": "full", "height": "medium" }, "ui:options": { "rows": 4, "emptyValue": "" } } } ``` #### Layout Properties ```json { "layout": { "width": "half", // quarter, half, three-quarter, full "height": "medium", // small, medium, large "group": "contact", // Group fields together "conditional": { // Conditional display "field": "hasPhone", "operator": "equals", "value": true } } } ``` #### Enhancement Properties ```json { "enhancement": { "icon": "user", "placeholder": { "en": "Enter your name", "es": "Ingrese su nombre" }, "helpText": { "en": "Your full legal name", "es": "Su nombre legal completo" }, "styling": { "variant": "outline", "size": "lg", "className": "custom-field" }, "validation": [ { "type": "required", "message": { "en": "This field is required", "es": "Este campo es obligatorio" } } ] } } ``` ## Field Types Reference ### Basic Fields #### Text Input ```json { "type": "string", "title": "Text Field", "minLength": 1, "maxLength": 255, "pattern": "^[a-zA-Z0-9\\s]+$" } ``` #### Text Area ```json { "type": "string", "format": "textarea", "title": "Description", "maxLength": 1000, "ui:widget": "textarea", "ui:options": { "rows": 4 } } ``` #### Number ```json { "type": "number", "title": "Price", "minimum": 0, "maximum": 999999, "multipleOf": 0.01 } ``` #### Boolean ```json { "type": "boolean", "title": "Active", "default": true } ``` #### Date & Time ```json { "birthday": { "type": "string", "format": "date", "title": "Date of Birth" }, "appointmentTime": { "type": "string", "format": "datetime", "title": "Appointment Time" }, "workingHours": { "type": "string", "format": "time", "title": "Working Hours" } } ``` ### Selection Fields #### Select Dropdown ```json { "type": "string", "title": "Country", "enum": ["US", "CA", "UK", "DE"], "enumNames": ["United States", "Canada", "United Kingdom", "Germany"], "default": "US" } ``` #### Multi-Select ```json { "type": "array", "title": "Skills", "items": { "type": "string", "enum": ["javascript", "python", "java", "csharp"] }, "uniqueItems": true, "minItems": 1, "maxItems": 5 } ``` #### Radio Buttons ```json { "type": "string", "title": "Subscription Plan", "enum": ["basic", "premium", "enterprise"], "enumNames": ["Basic", "Premium", "Enterprise"], "ui:widget": "radio" } ``` #### Checkboxes ```json { "type": "array", "title": "Interests", "items": { "type": "string", "enum": ["sports", "music", "technology", "travel"] }, "ui:widget": "checkboxes", "uniqueItems": true } ``` ### Advanced Fields #### File Upload ```json { "type": "string", "format": "data-url", "title": "Profile Picture", "ui:widget": "file", "accept": "image/*" } ``` #### Image with URL or Upload ```json { "type": "string", "format": "image-url-or-upload", "title": "Product Image", "ui:widget": "ImageInputWidget", "accept": "image/*" } ``` #### Rich Text Editor ```json { "type": "string", "format": "richtext", "title": "Product Description", "ui:widget": "richtext", "ui:layout": { "height": "large" } } ``` #### Reference Field ```json { "type": "string", "format": "reference", "title": "Related Product", "ui:widget": "ReferenceFieldWidget", "referenceConfig": { "entityType": "product", "displayField": "name", "searchFields": ["name", "sku"], "allowEmpty": true, "allowMultiSelect": false, "filterBy": { "category": "electronics" } } } ``` #### Multi-Select Reference Field ```json { "type": "array", "format": "reference", "title": "Related Categories", "ui:widget": "ReferenceFieldWidget", "referenceConfig": { "entityType": "category", "displayField": "name", "searchFields": ["name", "description"], "allowEmpty": true, "allowMultiSelect": true, "filterBy": { "type": "product_category" } } } ``` #### Color Picker ```json { "type": "string", "format": "color", "title": "Brand Color", "default": "#000000" } ``` #### Navigation List ```json { "type": "array", "title": "Menu Items", "items": { "type": "object", "title": "Menu Item", "properties": { "text": { "type": "string", "title": "Link Text" }, "url": { "type": "string", "format": "uri", "title": "URL" }, "target": { "type": "string", "title": "Target", "enum": ["_self", "_blank"], "default": "_self" } }, "required": ["text", "url"] }, "ui:options": { "addable": true, "orderable": true, "removable": true } } ``` ### Layout Fields #### Section Divider ```json { "type": "null", "title": "Contact Information", "description": "Please provide your contact details", "ui:widget": "section" } ``` ## Schema Validation ### Built-in Validation Rules #### String Validation ```json { "type": "string", "minLength": 3, "maxLength": 50, "pattern": "^[a-zA-Z\\s]+$" } ``` #### Number Validation ```json { "type": "number", "minimum": 0, "maximum": 100, "exclusiveMinimum": 0, "exclusiveMaximum": 100, "multipleOf": 0.5 } ``` #### Array Validation ```json { "type": "array", "minItems": 1, "maxItems": 10, "uniqueItems": true } ``` ### Custom Validation Rules ```json { "fieldName": { "type": "string", "title": "Password", "validation": [ { "type": "min_length", "value": 8, "message": { "en": "Password must be at least 8 characters long", "es": "La contraseña debe tener al menos 8 caracteres" } }, { "type": "regex", "value": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]", "message": { "en": "Password must contain uppercase, lowercase, number, and special character", "es": "La contraseña debe contener mayúsculas, minúsculas, números y caracteres especiales" } } ] } } ``` ### Cross-Field Validation ```json { "password": { "type": "string", "title": "Password" }, "confirmPassword": { "type": "string", "title": "Confirm Password", "validation": [ { "type": "field_equals", "value": "password", "message": { "en": "Passwords must match", "es": "Las contraseñas deben coincidir" } } ] } } ``` ### Conditional Validation ```json { "hasPhone": { "type": "boolean", "title": "I have a phone number" }, "phoneNumber": { "type": "string", "format": "phone", "title": "Phone Number", "dependencies": { "hasPhone": true }, "layout": { "conditional": { "field": "hasPhone", "operator": "equals", "value": true } } } } ``` ## Template Composition ### Inheritance Create base templates that can be extended: ```typescript // Base template const baseCustomerTemplate = { type: "object", title: "Base Customer", properties: { firstName: { type: "string", title: "First Name" }, lastName: { type: "string", title: "Last Name" }, email: { type: "string", format: "email", title: "Email" } }, required: ["firstName", "lastName", "email"] }; // Extended template const premiumCustomerTemplate = await client.schema.createComposedTemplate( baseTemplateId, { compositionRules: { inherit: ["firstName", "lastName", "email"], extend: [ { key: "accountManager", type: "string", title: "Account Manager" }, { key: "creditLimit", type: "number", title: "Credit Limit", minimum: 0 } ] } } ); ``` ### Override and Extend ```typescript const composedTemplate = await client.schema.createComposedTemplate( baseTemplateId, { compositionRules: { inherit: ["firstName", "lastName"], override: { email: { type: "string", format: "email", title: "Business Email", description: "Your company email address" } }, extend: [ { key: "company", type: "string", title: "Company Name" } ], exclude: ["personalNotes"], rename: { "phoneNumber": "businessPhone" } }, conflictResolution: "merge" } ); ``` ### Composition Rules ```typescript interface CompositionRules { inherit?: string[]; // Fields to inherit from base override?: Record<string, any>; // Fields to override extend?: Array<{ // New fields to add key: string; type: string; [key: string]: any; }>; exclude?: string[]; // Fields to exclude rename?: Record<string, string>; // Field name mappings } ``` ## Path-Based Organization ### Hierarchical Structure Organize templates using path-based hierarchy: ``` root/ ├── ecommerce/ ├── products/ ├── catalog ├── variants └── inventory ├── customers/ ├── profile ├── preferences └── billing └── orders/ ├── checkout ├── shipping └── returns └── hr/ ├── employees/ ├── profile ├── benefits └── performance └── recruiting/ ├── application ├── interview └── onboarding ``` ### Working with Paths ```typescript // Create template with path const template = await client.schema.createSchemaTemplate({ name: "Product Catalog", code: "product_catalog", path: "root/ecommerce/products/catalog", // ... other properties }); // Navigate by path const catalogTemplate = await client.schema.getSchemaTemplateByPath( "root/ecommerce/products/catalog" ); // Get children of a path const productTemplates = await client.schema.getSchemaTemplateChildren( "root/ecommerce/products" ); // Move template to new path await client.schema.moveSchemaTemplate( template.id, "root/ecommerce/inventory/products" ); // Get virtual hierarchy const hierarchy = await client.schema.getVirtualHierarchy(); ``` ### Virtual Hierarchy The system automatically generates a virtual folder structure for navigation: ```typescript interface VirtualHierarchyNode { path: string; name: string; type: 'template' | 'folder'; templateId?: number; depth: number; hasChildren: boolean; } ``` ## Versioning & Lifecycle ### Version Management ```typescript // Create new version const version = await client.schema.createAdvancedSchemaTemplateVersion( templateId, { version_number: "2.1.0", semantic_version: "2.1.0", schema_definition: updatedSchema, change_description: "Added new customer preference fields", version_type: "manual", breaking_changes: false, migration_required: false, compatibility_notes: "Backward compatible with v2.0.x", auto_publish_at: "2024-01-01T00:00:00Z" } ); // Get version history const versions = await client.schema.getEnhancedVersionHistory(templateId); // Compare versions const comparison = await client.schema.getVersionComparison( version1Id, version2Id ); // Rollback to previous version const rollback = await client.schema.rollbackSchemaTemplateVersion( templateId, previousVersionId, "Rollback due to validation issues" ); ``` ### Template Lifecycle Templates follow a defined lifecycle: 1. **Draft** - Under development 2. **Published** - Available for use 3. **Archived** - No longer active ```typescript // Publish template const published = await client.schema.publishSchemaTemplate( templateId, "2024-12-31T23:59:59Z" // Optional expiration ); // Update status const updated = await client.schema.updateSchemaTemplate(templateId, { status: "archived" }); ``` ## AI-Powered Enhancement ### Schema Generation Generate complete schemas using AI: ```typescript const aiSchema = await client.ai.generateSchema({ businessDescription: "Customer feedback form for restaurant service", industry: "hospitality", formType: "feedback", requirements: [ "Must collect customer contact information", "Need rating system for food, service, and ambiance", "Should allow photo uploads for evidence", "Include open-text feedback field" ], language: "en" }); // Execute the generated schema const template = await client.ai.executeSchemaCreation( aiSchema.schema, { templateName: "Restaurant Feedback Form", templateCode: "restaurant_feedback", category: "hospitality", description: "Comprehensive customer feedback collection" } ); ``` ### Field Enhancement Enhance individual fields with AI: ```typescript // Get field name suggestions const nameSuggestions = await client.ai.suggestFieldName({ fieldType: "email", businessContext: "customer registration", existingFields: ["firstName", "lastName"], userIntent: "collect primary contact email" }); // Get validation suggestions const validationSuggestions = await client.ai.suggestValidation({ fieldName: "customerEmail", fieldType: "email", businessDomain: "e-commerce" }); // Get field type suggestions const typeSuggestions = await client.ai.suggestFieldType({ fieldName: "customerRating", businessContext: "product review system" }); ``` ### Context Analysis Get AI recommendations for schema improvements: ```typescript const analysis = await client.ai.analyzeContext({ businessDomain: "e-commerce", existingSchema: currentSchema, userGoals: ["increase conversion", "reduce form abandonment"], targetAudience: "online shoppers" }); console.log("Recommendations:", analysis.recommendations); console.log("Insights:", analysis.insights); ``` ## Translation & Internationalization ### Multi-Language Support ```typescript // Define translatable fields const schema = { type: "object", title: "Customer Survey", properties: { satisfaction: { type: "string", title: "Satisfaction Level", enum: ["poor", "fair", "good", "excellent"], enumNames: ["Poor", "Fair", "Good", "Excellent"] } } }; // Add translations await client.schema.updateSchemaTranslations(templateId, "es", { "title": "Encuesta de Cliente", "properties.satisfaction.title": "Nivel de Satisfacción", "properties.satisfaction.enumNames.0": "Malo", "properties.satisfaction.enumNames.1": "Regular", "properties.satisfaction.enumNames.2": "Bueno", "properties.satisfaction.enumNames.3": "Excelente" }); // Get translations const translations = await client.schema.getSchemaTranslations( templateId, "es" ); ``` ### Supported Languages ```typescript const languages = await client.schema.getSupportedLanguages(); // Example output: [ { id: 1, code: "en", name: "English", native_name: "English", is_rtl: false, is_active: true, sort_order: 1 }, { id: 2, code: "es", name: "Spanish", native_name: "Español", is_rtl: false, is_active: true, sort_order: 2 } ] ``` ## Best Practices ### Schema Design 1. **Keep schemas focused** - Each template should have a single, clear purpose 2. **Use descriptive names** - Field names and titles should be clear and meaningful 3. **Provide helpful descriptions** - Use description fields to guide users 4. **Group related fields** - Use sections and layout groups to organize forms 5. **Consider mobile users** - Use appropriate field widths and layouts ### Validation Strategy 1. **Validate early and often** - Use both client-side and server-side validation 2. **Provide clear error messages** - Make validation errors helpful and actionable 3. **Use progressive validation** - Validate fields as users complete them 4. **Consider user experience** - Don't overwhelm users with too many validation rules ### Performance Optimization 1. **Use field ordering** - Define explicit field order for consistent rendering 2. **Minimize required fields** - Only mark fields as required when absolutely necessary 3. **Optimize for common use cases** - Design schemas for the most frequent scenarios 4. **Cache frequently used templates** - Implement caching for better performance ### Maintenance and Evolution 1. **Version strategically** - Create new versions for significant changes 2. **Document changes** - Always include clear change descriptions 3. **Test thoroughly** - Validate schemas with real data before publishing 4. **Plan for migration** - Consider how existing data will work with new versions 5. **Archive obsolete templates** - Keep the system clean by archiving unused templates ### Security Considerations 1. **Sanitize input** - Always sanitize form data before storage 2. **Validate permissions** - Ensure users can only access appropriate templates 3. **Protect sensitive data** - Use appropriate field types for sensitive information 4. **Audit changes** - Track who makes changes to templates and when ### Example: Complete E-commerce Product Schema ```json { "type": "object", "title": "Product Information", "description": "Comprehensive product catalog entry", "properties": { "basic_info": { "type": "null", "title": "Basic Information", "ui:widget": "section" }, "name": { "type": "string", "title": "Product Name", "description": "The display name for this product", "minLength": 1, "maxLength": 200, "ui:layout": { "width": "full" } }, "sku": { "type": "string", "title": "SKU", "description": "Stock Keeping Unit - unique product identifier", "pattern": "^[A-Z0-9-]+$", "maxLength": 50, "ui:layout": { "width": "half" } }, "category": { "type": "string", "title": "Category", "enum": ["electronics", "clothing", "books", "home", "sports"], "enumNames": ["Electronics", "Clothing", "Books", "Home & Garden", "Sports"], "ui:layout": { "width": "half" } }, "description": { "type": "string", "format": "richtext", "title": "Description", "description": "Detailed product description with formatting", "ui:widget": "richtext", "ui:layout": { "width": "full", "height": "large" } }, "pricing": { "type": "null", "title": "Pricing Information", "ui:widget": "section" }, "price": { "type": "number", "title": "Price", "description": "Base price in USD", "minimum": 0, "format": "currency", "ui:layout": { "width": "quarter" } }, "salePrice": { "type": "number", "title": "Sale Price", "description": "Discounted price (optional)", "minimum": 0, "format": "currency", "ui:layout": { "width": "quarter" } }, "costPrice": { "type": "number", "title": "Cost Price", "description": "Internal cost for margin calculation", "minimum": 0, "format": "currency", "ui:layout": { "width": "quarter" } }, "taxable": { "type": "boolean", "title": "Taxable", "description": "Is this product subject to sales tax?", "default": true, "ui:layout": { "width": "quarter" } }, "inventory": { "type": "null", "title": "Inventory Management", "ui:widget": "section" }, "trackInventory": { "type": "boolean", "title": "Track Inventory", "default": true, "ui:layout": { "width": "quarter" } }, "stockQuantity": { "type": "integer", "title": "Stock Quantity", "minimum": 0, "layout": { "width": "quarter", "conditional": { "field": "trackInventory", "operator": "equals", "value": true } } }, "lowStockThreshold": { "type": "integer", "title": "Low Stock Alert", "description": "Alert when stock falls below this level", "minimum": 0, "default": 10, "layout": { "width": "quarter", "conditional": { "field": "trackInventory", "operator": "equals", "value": true } } }, "allowBackorder": { "type": "boolean", "title": "Allow Backorder", "description": "Allow orders when out of stock", "default": false, "layout": { "width": "quarter", "conditional": { "field": "trackInventory", "operator": "equals", "value": true } } }, "media": { "type": "null", "title": "Product Media", "ui:widget": "section" }, "images": { "type": "array", "title": "Product Images", "description": "Upload or link product images", "items": { "type": "string", "format": "image-url-or-upload", "title": "Image" }, "minItems": 1, "maxItems": 10, "ui:widget": "ImageInputWidget", "ui:layout": { "width": "full" } }, "specifications": { "type": "null", "title": "Specifications", "ui:widget": "section" }, "weight": { "type": "number", "title": "Weight (kg)", "minimum": 0, "ui:layout": { "width": "quarter" } }, "dimensions": { "type": "object", "title": "Dimensions (cm)", "properties": { "length": { "type": "number", "title": "Length", "minimum": 0 }, "width": { "type": "number", "title": "Width", "minimum": 0 }, "height": { "type": "number", "title": "Height", "minimum": 0 } }, "ui:layout": { "width": "three-quarter" } }, "shipping": { "type": "null", "title": "Shipping Information", "ui:widget": "section" }, "shippingClass": { "type": "string", "title": "Shipping Class", "enum": ["standard", "heavy", "fragile", "hazardous"], "enumNames": ["Standard", "Heavy Item", "Fragile", "Hazardous"], "default": "standard", "ui:layout": { "width": "half" } }, "freeShipping": { "type": "boolean", "title": "Free Shipping", "default": false, "ui:layout": { "width": "quarter" } }, "isActive": { "type": "boolean", "title": "Active", "description": "Is this product available for sale?", "default": true, "ui:layout": { "width": "quarter" } } }, "required": ["name", "sku", "category", "price", "images"], "x-field-order": [ "basic_info", "name", "sku", "category", "description", "pricing", "price", "salePrice", "costPrice", "taxable", "inventory", "trackInventory", "stockQuantity", "lowStockThreshold", "allowBackorder", "media", "images", "specifications", "weight", "dimensions", "shipping", "shippingClass", "freeShipping", "isActive" ] } ``` This schema demonstrates: - Section organization with dividers - Conditional field display - Various field types and formats - Proper validation rules - Layout specifications - Logical field ordering By following these patterns and best practices, you can create robust, user-friendly dynamic schemas that scale with your application needs.