Files
interview-demo-code/.cursor/rules/form-builder.md
Nikita Kiselev 0e48b9d56d
Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
Squashed commit message
2026-03-11 22:17:44 +03:00

4.5 KiB

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 <style> blocks; standard CSS properties should be used if custom classes are needed.

Future Modifications

  • Adding Fields: Update constants/availableFields.js and ensure utils/fieldHelpers.js supports the new type.
  • Validation: FormKit validation rules string (e.g., "required|email") is edited as a raw string in FieldSettings. Complex validation builders would require a new UI component.