# FormBuilder System Context ## Architectural Overview The FormBuilder ecosystem is a strictly typed Vue 3 application module designed to generate standard FormKit Schema JSON. It eschews internal DTOs in favor of direct schema manipulation. ### Core Components 1. **FormBuilderView (`views/FormBuilderView.vue`)**: * **Role**: Smart container / Data fetcher. * **Responsibility**: Fetches form data from API (`GET /api/admin/forms/{alias}`), handles loading states, and passes data to `FormBuilder`. * **Contract**: Expects API response `{ data: { schema: Array, is_custom: Boolean, ... } }`. 2. **FormBuilder (`components/FormBuilder/FormBuilder.vue`)**: * **Role**: Main Orchestrator / State Owner. * **Responsibility**: Manages `v-model` (schema), mode switching (Visual/Code/Preview), and provides state to children. * **State Management**: Uses `defineModel` for `formFields` (schema) and `isCustom` (mode flag). Uses `provide('formFields')` and `provide('selectedFieldId')` for deep dependency injection. * **Modes**: * **Visual**: Drag-and-drop interface using `vuedraggable`. * **Code**: Direct JSON editing of the FormKit schema. Sets `isCustom = true`. * **Preview**: Renders the current schema using `FormKit`. 3. **FormCanvas (`components/FormBuilder/FormCanvas.vue`)**: * **Role**: Visual Editor Surface. * **Responsibility**: Renders the draggable list of fields. * **Implementation**: Uses `vuedraggable` bound to `formFields`. * **UX**: Implements "Ghost" and "Drag" classes for visual feedback. Handles selection logic. 4. **FieldsPanel (`components/FormBuilder/FieldsPanel.vue`)**: * **Role**: Component Palette. * **Responsibility**: Source of truth for available field types. * **Implementation**: Uses `vuedraggable` with `pull: 'clone', put: false` to spawn new fields. 5. **FieldSettings (`components/FormBuilder/FieldSettings.vue`)**: * **Role**: Property Editor. * **Responsibility**: Edits properties of the `selectedFieldId`. * **Constraint**: Must use PrimeVue components for all inputs. ## Data Flow & Invariants 1. **Schema Authority**: The FormKit Schema JSON is the single source of truth. There is no "internal model" separate from the schema. 2. **Reactivity**: * `formFields` is an Array of Objects. * Mutations must preserve reactivity. When using `v-model` or `provide/inject`, ensure array methods (splice, push, filter) are used correctly or replace the entire array reference if needed to trigger watchers. * **Immutability**: `useFormFields` composable uses immutable patterns (returning new array references) to ensure `defineModel` in parent detects changes. 3. **Mode Logic**: * Switching to **Code** mode sets `isCustom = true`. * Switching to **Visual** mode sets `isCustom = false`. * **Safety**: Switching modes triggers JSON validation. Invalid JSON prevents mode switch. 4. **Drag and Drop**: * Powered by `vuedraggable` (Sortable.js). * **Clone Logic**: `FieldsPanel` clones from `availableFields`. `FormCanvas` receives the clone. * **ID Generation**: Unique IDs are generated upon cloning/addition to ensure key stability. ## Naming & Conventions * **Tailwind**: Use `tw:` prefix for all utility classes (e.g., `tw:flex`, `tw:p-4`). * **Components**: PrimeVue components are the standard UI kit (Button, Panel, InputText, etc.). * **Icons**: FontAwesome (`fa fa-*`). * **Files**: PascalCase for components (`FormBuilder.vue`), camelCase for logic (`useFormFields.js`). ## Integration Rules * **Backend**: The backend stores the JSON blob directly. `FormBuilder` does not transform data before save; it emits the raw schema. * **API**: `useFormsStore` handles API communication. ## Pitfalls & Warnings * **vuedraggable vs @formkit/drag-and-drop**: We strictly use `vuedraggable`. Do not re-introduce `@formkit/drag-and-drop`. * **Watchers**: Avoid `watch` where `computed` or event handlers suffice, to prevent infinite loops in bidirectional data flow. * **Tailwind Config**: Do not use `@apply` with `tw:` prefixed classes in `