ADR-022: Theme Editing Pipeline Architecture

Prev Next

Context

The AppCMS Theme Editor allows administrators to configure branding and UI styling properties for a platform, including colors, typography, component styling, navigation appearance, and other UI tokens.

Historically, frontend implementations that bind UI components directly to backend theme payload structures become brittle over time due to:

  • backend schema changes
  • inconsistent naming conventions
  • nested structure changes
  • platform-specific variants
  • UI redesigns that require restructuring the form

Direct coupling between the UI layer and backend theme payloads leads to fragile systems where schema changes require UI rewrites.

To ensure long-term maintainability, the system must isolate:

  • backend schema representation
  • frontend form state structure
  • UI rendering layer

This separation allows UI changes without affecting persistence logic and backend schema evolution without breaking frontend code.

Decision

Theme editing will follow a normalized form-state pipeline architecture with explicit adapter layers between backend data and UI form state.

:::info Theme data lifecycle

Backend Theme Schema
        ↓
normalizeThemeAdapter
        ↓
RHF Form State
        ↓
UI Renderer
        ↓
dirtyFields detection
        ↓
serializeThemeAdapter
        ↓
API update
        ↓
Server response → form.reset()

:::

1. Normalization Layer

Backend theme data is passed through normalizeThemeAdapter.

Responsibilities:

  • convert backend schema into UI-friendly namespaced structure
  • enforce consistent naming conventions
  • provide stable keys for form binding
  • isolate UI from backend payload structure

:::info Example transformation

Backend
cta_primary_bg
    ↓
Normalized
uiElements.cta.primary.backgroundColor

:::

2. Form State Management

The normalized theme object populates a React Hook Form (RHF) instance.

RHF provides:

  • nested form state handling
  • efficient change detection
  • dirtyFields tracking
  • deterministic form updates

The RHF form state becomes the single source of truth for the editor UI.

3. UI Rendering Layer

  • The UI renders fields based on the normalized structure.
  • The UI must not depend on backend payload shape.
  • UI layout (tabs, accordions, visual builders, etc.) may change independently without affecting persistence logic.

4. Change Detection

Updates are triggered based on dirtyFields instead of isDirty.

This ensures:

  • deterministic detection of actual field modifications
  • prevention of unnecessary API calls
  • resilience to form resets and programmatic value updates

5. Serialization Layer

Before sending updates to the backend, the normalized structure is converted back into backend format via serializeThemeAdapter.

Responsibilities:

  • convert UI namespace structure back to backend schema
  • guarantee payload compatibility with the backend API
  • isolate backend schema expectations from the UI layer

6. Server Response Handling

After a successful update:

  1. The backend response is treated as the source of truth.
  2. Theme state is updated.
  3. form.reset() is called with the latest server values.

This ensures:

  • dirty state is cleared
  • UI reflects persisted data
  • frontend state remains synchronized with backend data.

Consequences

Positive

  • UI layer becomes replaceable without affecting persistence logic.
  • Backend schema changes are isolated to adapter layers.
  • Form state becomes predictable and easier to reason about.
  • Dirty field detection prevents redundant API calls.
  • Architecture supports autosave workflows and manual save workflows.
  • Enables future capabilities such as:
    • theme versioning
    • theme import/export
    • live preview editing
    • platform-specific theme variants
    • visual theme editors

Tradeoffs

  • Requires maintaining adapter layers for normalization and serialization.
  • Slightly higher architectural complexity compared to direct binding approaches.

However, this complexity prevents long-term coupling between UI and backend schema.

Notes

  • This ADR defines the canonical data lifecycle for all theme editing operations within AppCMS.
  • All theme editor implementations must conform to this pipeline to maintain separation between:
    • backend schema
    • frontend form state
    • UI rendering
  • normalizeThemeAdapter and serializeThemeAdapter form the integration boundary between backend and frontend systems and should be covered by unit tests to prevent schema drift issues.