---
description: Rules for Livewire, Alpine.js, and Blade templates.
globs: **/*.blade.php, **/*Component.php
alwaysApply: false
---
# Frontend Architecture

## Livewire vs. Alpine
- **Livewire:** Use ONLY for UI state, data fetching, and event listening.
- **Alpine.js:** Use for all CRUD operations (POST/PUT/DELETE) via `fetch()`.

## ⚠️ Critical Security Rule: No Direct Action Calls
- **NEVER** call Domain Actions (`CreateNode::create`) directly from Livewire components.
- **ALWAYS** send data to a Controller via `fetch()`/AJAX.
- **WHY?** Direct calls bypass Middleware, Auth policies, and CSRF protection.

## Delete Pattern
- Use the `<x-ipaas.delete-confirmation-modal>` component.
- Trigger via `onclick="confirmDelete(id, name, type)"`.
- Controller MUST return JSON for these requests.

## Form Field Semantic Naming Rule
- **Label and placeholder text MUST reflect the semantic type of the value the backend expects**, not just a human-readable approximation of the DB column name.
- If the backend interprets a config field as a **folder path** (e.g., passes it to `resolveFolderChain()`), the label must say "Path" and the placeholder must show a path example (e.g., `Tenant_A/Projects`). Using the word "ID" for a path field causes users to enter Drive folder IDs and receive confusing "Folder not found" errors.
- Rule: before writing a label, check how the stored value is consumed in the provider or backend service. Match the label vocabulary to the consumed format:
    - Path segment string → "Path", "Folder Path", placeholder `"FolderA/SubFolder"`
    - External provider ID (opaque alphanumeric) → "ID", "Folder ID", placeholder `"1BxiMVs0XRA..."`
    - Slug/handle → "Slug", "Handle", placeholder `"my-slug"`
