Appearance
Frontend-Backend Communication Flow Guide
Overview
This guide explains how data flows between Application-Frontend, Creative-Engine, and Application-Backend in the Cavai ecosystem, specifically for form styling and configuration.
Architecture Components
1. Application-Frontend (Vue.js + Vuex)
- Role: Configuration UI and state management
- Location:
/Users/nicolay/CavaiProduct/Application-Frontend - Key Files:
- Configuration components (Vue files)
- Vuex store (
src/store/modules/blocks.ts) - Type definitions (
src/pages/Chatbots/components/BuilderVisuals/Blocks/data/types.ts)
2. Creative-Engine (Vue.js Library)
- Role: Rendering and preview
- Location:
/Users/nicolay/CavaiProduct/Creative-Engine - Key Files:
- Rendering components (
src/components/creative/) - Type definitions (
src/interfaces/jsonTypes/payload-v2/index.ts)
- Rendering components (
3. Application-Backend (AdonisJS)
- Role: Data persistence and API
- Location:
/Users/nicolay/CavaiProduct/Application-Backend - Key Files:
- Creative JSON storage (
tmp/creatives/[creative-id]/assets/stub.js) - Database (Postgres)
- Creative JSON storage (
Communication Flow for Form Styling
Step 1: User Interaction (Frontend)
User changes font size in FormSubmitButtonSection.vue
↓
Component emits: @update:fontSettings
↓
FormConfiguration.vue receives event
↓
Calls: updateValue($event, 'submitButtonProperties.fontSize')Step 2: State Management (Vuex)
updateValue() calls Vuex mutation
↓
Store updates: blockData.submitButtonProperties.fontSize = '16px'
↓
Vue reactivity triggers re-render of configuration UIStep 3: Data Persistence (Backend)
Vuex store automatically syncs to backend
↓
POST request to Application-Backend API
↓
Backend saves to: tmp/creatives/[id]/assets/stub.js
↓
Database (Postgres) updated with complete creative JSONStep 4: Preview Rendering (Creative-Engine)
Creative-Engine receives updated props via iframe communication
↓
CreativeFormBlock.vue gets new submitButtonProperties
↓
Computed styles update: getSubmitButtonStyles()
↓
DOM re-renders with new font sizeKey Communication Patterns
1. Event Emission Pattern
vue
<!-- Child Component -->
<FontSizeSection
:font-size="buttonStyles.fontSize"
@update:value="$emit('update:fontSettings', $event)"
/>
<!-- Parent Component -->
<FormSubmitButtonSection
@update:fontSettings="updateFontSettings"
/>
<!-- Configuration Component -->
<script>
methods: {
updateFontSettings(fontData) {
this.updateValue(fontData, 'submitButtonProperties.fontSize')
}
}
</script>2. Props Down Pattern
vue
<!-- Parent passes data down -->
<FormSubmitButtonSection
:button-styles="blockData.submitButtonProperties || {}"
/>
<!-- Child receives and uses -->
<script>
props: {
buttonStyles: {
type: Object,
default: () => ({})
}
}
</script>3. Store Update Pattern
javascript
// In configuration components
methods: {
updateValue(value, path) {
// Updates Vuex store
this.$store.commit('blocks/updateBlockValue', {
blockName: this.blockData.blockName,
path: path,
value: value
})
}
}Data Flow Diagram
┌─────────────────┐ Events ┌─────────────────┐
│ UI Component │ ──────────→ │ Config Component│
│ (FontSection) │ │(FormConfig.vue) │
└─────────────────┘ └─────────────────┘
│
│ updateValue()
▼
┌─────────────────┐ ┌─────────────────┐
│ Creative-Engine │ │ Vuex Store │
│ (Rendering) │ ◄────────────│ (State Mgmt) │
└─────────────────┘ Props └─────────────────┘
▲ │
│ │ API Call
│ iframe ▼
│ communication ┌─────────────────┐
└──────────────────────│ Application- │
│ Backend │
└─────────────────┘File Responsibilities
Configuration Files (Application-Frontend)
FormConfiguration.vue
├── Manages form-level settings
├── Handles submit button configuration
├── Emits: updateValue($event, 'submitButtonProperties.*')
└── Receives: props from parent, events from children
FormSubmitButtonSection.vue
├── Manages submit button styling UI
├── Emits: @update:fontSettings, @update:alignment, etc.
└── Receives: :button-styles prop
FontSizeSection.vue
├── Manages font size input
├── Emits: @update:value with {fontSize: '16px'}
└── Receives: :font-size propRendering Files (Creative-Engine)
CreativeFormBlock.vue
├── Receives: formProps via props
├── Computes: getSubmitButtonStyles()
├── Renders: <button :style="submitButtonStyles">
└── Updates: when props change (reactive)Type Definitions
Application-Frontend/types.ts
├── FormProperties interface
├── FormInputProperties interface
└── Used by: Configuration components
Creative-Engine/payload-v2/index.ts
├── FormProperties interface (matching)
├── FormInputProperties interface (matching)
└── Used by: Rendering componentsCommon Issues and Solutions
Issue 1: Font Settings Not Working
Problem: Font changes in UI don't reflect in preview Root Cause: Event emission chain broken or wrong property path Solution:
- Check event emission:
@update:fontSettings="updateFontSettings" - Verify property path:
'submitButtonProperties.fontSize' - Ensure Creative-Engine uses:
formProps.submitButtonProperties?.fontSize
Issue 2: Real-time Updates Not Working
Problem: Changes save but don't show immediately in preview Root Cause: Creative-Engine runs in iframe, isolated from Vuex Solution:
- Manual iframe reload
- Creative republish
- Check
DataStore.creativeSettingsis reactive
Issue 3: Type Mismatches
Problem: TypeScript errors between Frontend and Engine Root Cause: Interface definitions don't match Solution:
- Keep interfaces synchronized between codebases
- Use same property names and types
- Run
npm run build:libraryafter Creative-Engine changes
Development Workflow
Adding New Styling Property
- Define in Types (both codebases)
typescript
// Application-Frontend/types.ts
export interface FormProperties {
submitButtonProperties?: {
newProperty?: string
}
}
// Creative-Engine/payload-v2/index.ts
export interface FormProperties {
submitButtonProperties?: {
newProperty?: string
}
}- Add to Defaults
javascript
// Application-Frontend/defaults.ts
export const formDefaults = {
submitButtonProperties: {
newProperty: 'defaultValue'
}
}- Create UI Component
vue
<!-- NewPropertySection.vue -->
<template>
<input
:value="newProperty"
@input="$emit('update:value', $event.target.value)"
/>
</template>- Wire Up Events
vue
<!-- FormSubmitButtonSection.vue -->
<NewPropertySection
:new-property="buttonStyles.newProperty"
@update:value="$emit('update:newProperty', $event)"
/>
<!-- FormConfiguration.vue -->
<FormSubmitButtonSection
@update:newProperty="updateValue($event, 'submitButtonProperties.newProperty')"
/>- Implement Rendering
vue
<!-- CreativeFormBlock.vue -->
<script>
computed: {
getSubmitButtonStyles() {
return {
newProperty: this.formProps.submitButtonProperties?.newProperty || 'defaultValue'
}
}
}
</script>- Build and Test
bash
# In Creative-Engine (if using npm run watch, this happens automatically)
npm run build:library
# Test in Application-Frontend
# Changes should flow: UI → Vuex → Backend → Creative-Engine → DOMDebugging Tips
1. Check Event Flow
javascript
// Add to configuration components
methods: {
updateFontSettings(fontData) {
console.log('Font settings updated:', fontData)
this.updateValue(fontData, 'submitButtonProperties.fontSize')
}
}2. Check Store State
javascript
// In Vue DevTools or component
computed: {
debugBlockData() {
console.log('Current block data:', this.blockData)
return this.blockData
}
}3. Check Creative-Engine Props
javascript
// In CreativeFormBlock.vue
computed: {
debugFormProps() {
console.log('Form props received:', this.formProps)
return this.formProps
}
}4. Check Backend Persistence
bash
# Check creative JSON file
cat /Users/nicolay/CavaiProduct/Application-Backend/tmp/creatives/[creative-id]/assets/stub.js
# Check log file
cat /Users/nicolay/CavaiProduct/Application-Backend/tmp/creatives/[creative-id]/log.txtThis communication flow ensures that styling changes made in the frontend configuration UI are properly persisted and rendered in the Creative-Engine preview.