Skip to Content

Platform Skin Model

SAM AI Platform Skin Architecture Model

SAM AI Platform Skin Architecture Model


🎯 Executive Summary

SAM AI uses a three-layer architecture where data, framework, and UI are completely separated:

  1. ai_brain = Pure data layer (ALL models, no views)
  2. ai_sam = Framework + Canvas core + Controllers (business logic, no data models)
  3. Platform Skins = UI renderers only (views, JS/CSS, specific to each platform)
Key Principle:
ONE data layer (ai_brain) + ONE framework (ai_sam) + MANY skins (platforms) = Infinite extensibility with data safety

πŸ“š Terminology

Platform Skin:

A Platform Skin is a UI-only module that provides:

  • βœ… Views (XML)
  • βœ… Frontend code (JavaScript/CSS)
  • βœ… Platform-specific renderers
  • βœ… Optional: Platform-specific controllers (if needed for UI logic)
  • ❌ NO DATA MODELS (all data lives in ai_brain)

Examples:

  • ai_sam_workflows = Workflow automation skin (N8N-style UI)
  • ai_sam_memory = Knowledge graph visualization skin
  • ai_sam_creatives = Multimedia canvas skin
Debug Isolation:
"Debug UI issues 1 platform at a time" - Each skin is independent, uninstalling won't affect data

πŸ—οΈ Three-Layer Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ LAYER 3: PLATFORM SKINS (UI Layer) β”‚ β”‚ Purpose: Provide specialized UI/UX for different use cases β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ ai_sam_workflows β”‚ β”‚ ai_sam_memory β”‚ β”‚ai_sam_creativesβ”‚ β”‚ β”‚ β”‚ (N8N Workflows) β”‚ β”‚ (Knowledge Graph)β”‚ β”‚ (Multimedia) β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”‚ β”‚ βœ… Views (XML) β”‚ β”‚ βœ… Views (XML) β”‚ β”‚ βœ… Views (XML)β”‚ β”‚ β”‚ β”‚ βœ… JS Renderer β”‚ β”‚ βœ… JS Renderer β”‚ β”‚ βœ… JS Rendererβ”‚ β”‚ β”‚ β”‚ βœ… CSS Styles β”‚ β”‚ βœ… CSS Styles β”‚ β”‚ βœ… CSS Styles β”‚ β”‚ β”‚ β”‚ βœ… Controllers* β”‚ β”‚ βœ… Controllers* β”‚ β”‚ βœ… Controllers*β”‚ β”‚ β”‚ β”‚ ❌ NO MODELS β”‚ β”‚ ❌ NO MODELS β”‚ β”‚ ❌ NO MODELS β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ *Controllers only if platform-specific UI logic required β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ depends on β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ LAYER 2: AI_SAM (Framework Layer) β”‚ β”‚ Purpose: Provide canvas core, services, and universal logic β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Canvas Skeleton Core: β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ canvas_sizer.js (universal sizing) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ canvas_engine.js (pan/zoom/grid) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ node_manager.js (CRUD operations) β”‚ β”‚ β”‚ β”‚ └── platform_loader.js (dynamic skin injection) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Services: β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai_service.py (Claude API integration) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai_context_builder.py (all-knowing context) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai_voice_service.py (Whisper integration) β”‚ β”‚ β”‚ β”‚ └── ai_registry_watcher.py (module monitor) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Universal Controllers (query engines): β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ canvas_controller.py (canvas API) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sam_ai_chat_controller.py (chat endpoints) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sam_session_controller.py (session management) β”‚ β”‚ β”‚ β”‚ └── [Future: query engine controllers] β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Site-Wide UI: β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sam_ai_chat_widget.js (global chat) β”‚ β”‚ β”‚ β”‚ └── sam_ai_token_counter.js (cost tracking) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ ❌ NO DATA MODELS (framework code only) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ depends on β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ LAYER 1: AI_BRAIN (Data Layer) β”‚ β”‚ Purpose: Persistent data storage - ALL models live here β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ πŸ“Š ALL DATA MODELS - PROTECTED AND PERSISTENT β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Core SAM AI Data: β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.service.config (API configuration) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.conversation (chat threads) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.message (messages) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.token.usage (usage tracking) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sam.user.profile (user profiles) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sam.user.settings (user settings) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sam.mode.context (power prompts) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ sam.chat.session (chat sessions) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ canvas.platform (platform registry) β”‚ β”‚ β”‚ β”‚ └── ai.branch (branch meta-architecture) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Workflow Data (for ai_sam_workflows skin): β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ canvas (workflow definitions) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ executions (execution history - audit trail) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ nodes (node instances) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ connections (node connections) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ business.unit (business units) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ api.credentials (API keys - sensitive) β”‚ β”‚ β”‚ β”‚ └── workflow.template (workflow templates) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Memory Data (for ai_sam_memory skin): β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.memory.config (memory system config) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.conversation.import (imported conversations) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.document.extractor (document extraction) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ ai.extractor.plugin (learned extraction patterns) β”‚ β”‚ β”‚ β”‚ └── ai.graph.service (graph DB interface) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Creatives Data (for ai_sam_creatives skin): β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ creatives.project (creative projects) β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ creatives.asset (multimedia assets) β”‚ β”‚ β”‚ β”‚ └── creatives.landing.card (landing cards) β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ ❌ NO VIEWS, NO CONTROLLERS (pure data) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‹ What Goes Where

ai_brain (Data Layer)

Principle: If losing it would make a customer angry, it belongs here.

Contains:

  • βœ… ALL data models (ir.model records)
  • βœ… User data (workflows, projects, conversations)
  • βœ… Audit trails (executions, token usage)
  • βœ… Sensitive data (API credentials, user profiles)
  • βœ… Configuration data (settings, templates)

Does NOT contain:

  • ❌ Views (no XML files)
  • ❌ Controllers (no HTTP endpoints)
  • ❌ Frontend code (no JS/CSS)
Example Models:
# ai_brain/models/__init__.py

# Core SAM AI models
from . import ai_service_config
from . import ai_conversation
from . import ai_message
from . import sam_user_profile

# Workflow data (used by ai_sam_workflows skin)
from . import canvas              # Workflow definitions
from . import executions          # Execution history
from . import nodes               # Node instances
from . import connections         # Node connections
from . import api_credentials     # API keys

# Memory data (used by ai_sam_memory skin)
from . import ai_memory_config
from . import ai_conversation_import

# Creatives data (used by ai_sam_creatives skin)
from . import creatives_project
from . import creatives_asset
Uninstall Safety:
  • ❌ Cannot uninstall ai_brain (base dependency)
  • βœ… Data protected forever

ai_sam (Framework Layer)

Principle: Universal infrastructure that ALL platforms need.

Contains:

  • βœ… Canvas Skeleton Core (universal canvas engine)
  • βœ… Platform Loader (dynamic skin injection)
  • βœ… Universal Services (Claude API, context builder)
  • βœ… Universal Controllers (query engines, chat API)
  • βœ… Site-wide UI (chat widget, token counter)

Does NOT contain:

  • ❌ Data models (belongs in ai_brain)
  • ❌ Platform-specific UI (belongs in skins)
Structure:

ai_sam/
β”œβ”€β”€ models/ ← ❌ SHOULD BE EMPTY (no data models)
β”œβ”€β”€ controllers/ ← βœ… Universal controllers
β”‚ β”œβ”€β”€ canvas_controller.py (canvas API - query engine)
β”‚ β”œβ”€β”€ sam_ai_chat_controller.py (chat endpoints)
β”‚ β”œβ”€β”€ sam_session_controller.py (session management)
β”‚ └── [future query controllers]
β”œβ”€β”€ static/src/
β”‚ β”œβ”€β”€ core/ ← βœ… Canvas skeleton core
β”‚ β”‚ β”œβ”€β”€ canvas_sizer.js
β”‚ β”‚ β”œβ”€β”€ canvas_engine.js
β”‚ β”‚ β”œβ”€β”€ node_manager.js
β”‚ β”‚ └── platform_loader.js
β”‚ β”œβ”€β”€ js/ ← βœ… Universal UI components
β”‚ β”‚ β”œβ”€β”€ sam_ai_chat_widget.js
β”‚ β”‚ └── sam_ai_token_counter.js
β”‚ └── css/ ← βœ… Universal styles
└── views/ ← βœ… Universal views (menu structure, canvas container)

Controllers in ai_sam (Query Engines):

Controllers in ai_sam are universal query engines that work across all platforms:

# ai_sam/controllers/canvas_controller.py
class CanvasController(http.Controller):
    """
    Universal canvas API - works for ALL platforms
    Queries ai_brain models, returns data to any skin
    """

    @http.route('/sam/canvas/list', type='json', auth='user')
    def list_canvases(self, platform=None):
        # Query ai_brain.canvas model
        # Can filter by platform (workflows, memory, creatives)
        Canvas = request.env['canvas']
        return Canvas.search_read([...])

    @http.route('/sam/canvas/save', type='json', auth='user')
    def save_canvas(self, canvas_id, data):
        # Save to ai_brain.canvas model
        # Works regardless of which skin is using it
        Canvas = request.env['canvas']
        canvas = Canvas.browse(canvas_id)
        canvas.write(data)
        return {'success': True}
Key Insight (Hybrid Approach - Option C):
If 2+ platforms will use it β†’ ai_sam (universal controller)
If only 1 platform uses it β†’ That platform's controller (direct to ai_brain)

This avoids unnecessary abstraction while preventing code duplication. Platform controllers CAN access ai_brain directly when needed.

Platform Skins (UI Layer)

Principle: UI-only modules that provide specialized experiences for specific use cases.

Contains:

  • βœ… Views (XML) - Platform-specific forms, kanban, tree views
  • βœ… JavaScript Renderers - Platform-specific canvas rendering
  • βœ… CSS Styles - Platform-specific styling
  • βœ… Platform-Specific Controllers (optional, only if needed for UI logic)
  • βœ… Seed Data (XML) - Platform registration, demo data (reinstallable)

Does NOT contain:

  • ❌ Data models (belongs in ai_brain)
  • ❌ Universal controllers (belongs in ai_sam)
Structure:

ai_sam_workflows/ ← Platform Skin (example)
β”œβ”€β”€ models/ ← ❌ SHOULD BE EMPTY or minimal extensions
β”œβ”€β”€ controllers/ ← βœ… Platform-specific controllers (if needed)
β”‚ └── workflow_import_controller.py (workflow-specific UI logic)
β”œβ”€β”€ views/ ← βœ… Platform-specific views
β”‚ β”œβ”€β”€ workflow_definition_views.xml
β”‚ β”œβ”€β”€ workflow_execution_views.xml
β”‚ └── workflow_menus.xml
β”œβ”€β”€ static/src/
β”‚ └── workflows/ ← βœ… Platform-specific renderer
β”‚ β”œβ”€β”€ workflow_renderer.js (N8N-style node rendering)
β”‚ β”œβ”€β”€ workflow_toolbar.js (workflow-specific tools)
β”‚ └── workflow_styles.css
β”œβ”€β”€ data/ ← βœ… Seed data (reinstallable)
β”‚ β”œβ”€β”€ workflow_platform.xml (platform registration)
β”‚ └── workflow_templates.xml (demo templates)
└── security/ ← βœ… UI-specific security rules
└── ir.model.access.csv (view access only)

Platform-Specific Controllers:

Question: Do platform skins have their own controllers?
Answer: YES, but ONLY for platform-specific UI logic.

Rule:
  • βœ… Universal query engines β†’ ai_sam (work across all platforms)
  • βœ… Platform-specific UI logic β†’ Platform skin (only needed for that skin)
Example:
# ai_sam_workflows/controllers/workflow_import_controller.py
class WorkflowImportController(http.Controller):
    """
    Workflow-specific controller for N8N JSON import
    This is UI logic specific to the workflows skin
    """

    @http.route('/workflows/import/n8n', type='http', auth='user')
    def import_n8n_json(self, file):
        # Parse N8N JSON (specific to workflows platform)
        # Create canvas, nodes, connections in ai_brain
        # Return workflow ID
        pass

    @http.route('/workflows/export/n8n', type='http', auth='user')
    def export_n8n_json(self, workflow_id):
        # Read from ai_brain.canvas
        # Convert to N8N JSON format (specific to workflows platform)
        # Return JSON file
        pass
Key Principle (Hybrid Approach):
Universal operations (used by 2+ platforms) β†’ ai_sam controller
Platform-specific operations (used by 1 platform) β†’ Platform skin controller (direct to ai_brain)

Benefits:
  • βœ… No unnecessary abstraction layers
  • βœ… No code duplication (DRY principle)
  • βœ… Platform controllers can access ai_brain directly
  • βœ… Shared logic centralized where it adds value

🎯 Benefits of Platform Skin Architecture

1. Data Safety:

  • βœ… Uninstall any platform skin β†’ Data remains safe in ai_brain
  • βœ… Reinstall platform skin β†’ Data is still there
  • βœ… Compliance-friendly (audit trails protected)

2. Debug Isolation:

  • βœ… "Debug UI issues 1 platform at a time"
  • βœ… Workflows broken? Uninstall ai_sam_workflows, debug, reinstall
  • βœ… Other platforms unaffected
  • βœ… Data untouched

3. Flexible Frontend Development:

  • βœ… Build web forms that query ai_brain directly (no ai_sam needed)
  • βœ… Build mobile app that hits ai_sam controllers
  • βœ… Build external dashboard that visualizes ai_brain data
  • βœ… Replace entire platform skin without losing data

4. Clean Separation:

  • βœ… Frontend developers work on skins (no database risk)
  • βœ… Backend developers work on ai_brain (no UI complexity)
  • βœ… Framework developers work on ai_sam (universal infrastructure)

πŸ“Š Module Dependencies

ai_sam_workflows  ─┐
ai_sam_memory     ──
ai_sam_creatives  ─┼──→  ai_sam  ──→  ai_brain  ──→  base (Odoo core)
[future skins]    β”€β”˜

Dependency Direction:
Skins depend on ai_sam
ai_sam depends on ai_brain
ai_brain depends on base

Data Flow:
Skins (UI) β†’ ai_sam (controllers/query engines) β†’ ai_brain (data)

Installation Order:

  1. base (Odoo core)
  2. ai_brain (data layer)
  3. ai_sam (framework)
  4. Platform skins (optional, any order)

Uninstallation:

  • βœ… Can uninstall any skin (data safe)
  • βœ… Can uninstall ai_sam (if no skins installed)
  • ❌ Cannot uninstall ai_brain (base dependency, data layer)

πŸ”„ Uninstall Strategy

Platform Skin Uninstall:

# ai_sam_workflows/models/workflow_uninstall_wizard.py
class WorkflowUninstallWizard(models.TransientModel):
    _name = 'workflow.uninstall.wizard'

    def check_data_exists(self):
        # Check if workflows exist in ai_brain
        Canvas = self.env['canvas']
        workflow_count = Canvas.search_count([('canvas_type', '=', 'workflow')])

        if workflow_count > 0:
            # Warn user
            return {
                'type': 'ir.actions.act_window',
                'name': 'Workflows Exist',
                'res_model': 'workflow.uninstall.wizard',
                'view_mode': 'form',
                'target': 'new',
            }

    def export_and_uninstall(self):
        # Export workflow data (CSV/JSON)
        # User downloads backup
        # Then allow uninstall
        # Data remains in ai_brain (still accessible if reinstalled)
        pass
Workflow:
  1. User clicks "Uninstall ai_sam_workflows"
  2. Wizard checks ai_brain for workflow data
  3. If data exists β†’ Offer export option
  4. User downloads backup (optional)
  5. Uninstall proceeds
  6. Data remains in ai_brain (not deleted)
  7. If user reinstalls β†’ Data is still there!

πŸš€ Future: Query Engines and Web Forms

Your vision:
"Now I could start to build our next step around ai_brain and initiate a simple web form and various query engines"

Architecture Enables This:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ MULTIPLE FRONTENDS (all query same data) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Platform β”‚ β”‚ Web Forms β”‚ β”‚ Mobile β”‚ β”‚ β”‚ β”‚ Skins β”‚ β”‚ (Simple UI) β”‚ β”‚ App β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ ↓ ↓ ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ai_sam (Query Engines/Controllers) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ canvas_controller.py β”‚ β”‚ β”‚ β”‚ query_controller.py β”‚ β”‚ β”‚ β”‚ workflow_query_controller.py β”‚ β”‚ β”‚ β”‚ conversation_query_controller.py β”‚ β”‚ β”‚ β”‚ [future controllers] β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ai_brain (Data) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ ALL MODELS β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Example: Simple Web Form (No Platform Skin Needed)

<!-- simple_web_module/views/simple_form.xml -->
<form string="Query Workflows">
    <field name="date_from"/>
    <field name="date_to"/>
    <button name="query_workflows" string="Search" type="object"/>
</form>
# simple_web_module/models/simple_query.py
class SimpleQuery(models.TransientModel):
    _name = 'simple.query'

    date_from = fields.Date()
    date_to = fields.Date()

    def query_workflows(self):
        # Query ai_brain directly!
        Canvas = self.env['canvas']
        workflows = Canvas.search([
            ('create_date', '>=', self.date_from),
            ('create_date', '<=', self.date_to),
        ])

        # Return data (no complex UI needed)
        return {
            'type': 'ir.actions.act_window',
            'name': 'Results',
            'res_model': 'canvas',
            'view_mode': 'tree,form',
            'domain': [('id', 'in', workflows.ids)],
        }
Key Point:
Because ALL data is in ai_brain, you can query it from ANYWHERE (platform skins, web forms, mobile apps, external APIs)

πŸ“ Summary

Golden Rules:

  1. Data Layer (ai_brain):
    • ALL data models
    • No views, no controllers
    • Protected, persistent, queryable
  2. Framework Layer (ai_sam):
    • Canvas skeleton core
    • Universal services
    • Universal controllers (query engines)
    • No data models
  3. UI Layer (Platform Skins):
    • Views (XML)
    • Renderers (JS/CSS)
    • Platform-specific controllers (UI logic only)
    • No data models
  4. Controllers (Hybrid Approach - Option C):
    • Universal operations (2+ platforms) β†’ ai_sam
    • Platform-specific operations (1 platform) β†’ Platform skin (direct to ai_brain)
    • Optimize for simplicity, not abstraction
Test:
If losing it would make a customer angry β†’ ai_brain
If it's UI-specific and safe to remove β†’ Platform skin
If it's universal infrastructure β†’ ai_sam

πŸ“– Lessons Learned: Workflows Platform Correction (2025-10-12)

The Mistake:

During Phase 3 extraction (2025-10-11), we initially moved workflow data models to ai_sam_workflows.

What happened:
  • Moved 20 data models from ai_brain to ai_sam_workflows
  • Treated ai_sam_workflows as standalone module instead of Platform Skin
  • Followed incorrect pattern from initial extraction
Impact:
  • ❌ Uninstalling ai_sam_workflows would delete user workflow data
  • ❌ Violated data safety principles
  • ❌ Broke compliance/audit trail requirements (HIPAA, GDPR, SOX)
  • ❌ Contradicted original ai_brain design intent (pure data layer)
  • ❌ Broke "debug UI issues 1 platform at a time" strategy
  • ❌ Created data loss risk on module uninstall

The Fix:

Moved all 20 workflow data models back to ai_brain (2025-10-12).

Actions Taken:
  1. Archived current state (safety first)
  2. Moved all 20 model files back to ai_brain/models/
  3. Updated ai_brain/models/__init__.py with imports
  4. Cleared ai_sam_workflows/models/__init__.py (UI-only)
  5. Updated security rules (already in ai_brain)
  6. Updated both module manifests with Platform Skin documentation
  7. Created comprehensive correction summary
Result:
  • βœ… Data survives module uninstalls
  • βœ… Audit trails protected
  • βœ… Platform Skin Model correctly implemented
  • βœ… "Debug UI issues 1 platform at a time" strategy enabled
  • βœ… Compliance requirements met
  • βœ… Uninstall wizard strategy now viable

Key Insights:

The Golden Rule:

"If losing it would make a customer angry, it belongs in ai_brain" - This rule is non-negotiable.

Data vs UI Test:
  • Would losing this on uninstall anger customers? β†’ ai_brain
  • Is this just a UI preference? β†’ Platform skin
  • Is this execution history or audit data? β†’ ai_brain (always!)

Real-World Scenario:

❌ BAD:
User: "I want to uninstall the workflows UI to debug issues"
Developer: "Sure, uninstalling ai_sam_workflows..."
User: "Wait, what happened to all my workflows?!"
Developer: "Oh no... they're gone..." ❌
βœ… CORRECT:
User: "I want to uninstall the workflows UI to debug issues"
Developer: "Sure, uninstalling ai_sam_workflows..."
User: "Great! When I reinstall, will my workflows still be there?"
Developer: "Absolutely! All data is safe in ai_brain" βœ…

Compliance Perspective:

  • HIPAA: Audit trails must be immutable and persistent
  • GDPR: Data retention policies must be enforced
  • SOX: Financial transaction history cannot be deleted
  • Platform skins: UI preferences, not data stores

Apply to Other Modules:

Module Status Action
ai_sam_memory βœ… Already correct Ensure only UI components in module
ai_sam_creatives βœ… Already correct Ensure only UI components in module
Future Platform Skins Follow this pattern NEVER put data models in platform modules

Rules for Future Platform Skins:

  • ❌ NEVER put data models in platform modules
  • βœ… ALWAYS put data models in ai_brain
  • βœ… Platform skins = Views + JS/CSS + Platform-specific controllers only

Was this helpful?