# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```bash # Development npm run dev # Vite dev server (hot-reload) php artisan serve # Laravel dev server # Build npm run build # Production Vite build # Database php artisan migrate php artisan migrate:fresh --seed # Testing php artisan test php artisan test --filter=TestName # Livewire php artisan livewire:make ComponentName ``` ## Architecture **Stack:** Laravel 13 + Livewire 4 + Alpine.js + Tailwind CSS 4 + Vite + Laravel Reverb (WebSockets) ### Livewire Components (`app/Livewire/`) Each feature lives in its own namespace folder with a matching `resources/views/livewire/` blade. Components use `.layout('layouts.app')` in their `render()` method. | Namespace | Route | Purpose | |-----------|-------|---------| | `Calendar/WeekCanvas` | `/calendar` | Main calendar view (week/day/month) | | `Calendar/Sidebar` | — | Slide-in event create/edit panel | | `Activities/Index` | `/activities` | Activity log with search, filter, pagination | | `Automation/Index` | `/automations` | Automation rules with slide-in config panel | | `Integration/Index` | `/integrations` | Google Calendar + Outlook OAuth integration cards | | `Settings/Index` | `/settings` | Tab-based settings (profile, security, notifications, SMTP) | | `Contacts/Index` | `/contacts` | Contact management | | `Agent/Index` | `/agent` | AI agent interface | ### Models (`app/Models/`) - **User** — has `settings` (json column), `timezone`, `locale`, `hasFeature(string $key)` helper - **Event** — calendar events with color (hex), recurrence, user-owned - **Activity** — audit log; use `Activity::log($userId, $type, $title, ...)` static factory; `visual()` returns icon/bg/text; `typeLabel()` returns German label - **Automation** — user automations with `config` (json); `cfg($key, $default)` helper - **CalendarIntegration** — Google/Outlook OAuth tokens; unique on `[user_id, provider]` - **Reminder**, **Contact**, **Plan**, **Feature**, **Subscription** — supporting models ### Plan / Feature Gating `User::hasFeature('feature_key')` checks the user's active subscription plan against the `features` pivot. Used for Pro-only functionality (e.g., sync modes in integrations). ### Calendar Views The main calendar is `WeekCanvas.php` / `week-canvas.blade.php`. It renders week, day, and month views with: - `resources/js/calendar-week-canvas.js` — Alpine.js component handling drag, resize, dblclick-to-create - `resources/js/calendar-interact.js` — interact.js integration for resizing - Overlapping event layout: greedy depth/column assignment in the blade's `@php` block - Solid pastel backgrounds: `rgb(255-(255-r)*0.18, ...)` formula (not transparent rgba) ### OAuth Integration Flow `app/Http/Controllers/Integration/` — full-page redirect controllers (not Livewire). After callback, redirect to `/integrations?connected=google`. The Livewire Integration component reads the `?connected` query param on mount to show success state. ### Event System (Livewire ↔ Alpine) - `$this->dispatch('sidebar:createEvent', date: ..., time: ...)` — opens sidebar - `$this->dispatch('eventCreated')` — calendar refreshes via `$listeners = ['eventCreated' => '$refresh']` - `$this->dispatch('notify', ['type' => 'success', 'message' => '...'])` — toast notifications - `$this->dispatch('openModal', 'component.name', [...])` — wire-elements/modal ### Translations `t('key')` is a custom helper (wraps `__()`) used throughout. Language files in `resources/lang/`. Supported locales: `de`, `en` (configured in `config/app.php` under `locales`). ### Design System Consistent Tailwind patterns across all views: - Cards: `bg-white border border-gray-100 rounded-xl shadow-sm` - Primary color: `indigo-600` / `bg-indigo-50` - Section headings: `text-xl font-semibold text-gray-800` - Badges/chips: `text-[10px] font-medium px-1.5 py-0.5 rounded-md` - Danger: `text-red-500 hover:text-red-600` ### Authentication Custom auth middleware: `auth.custom` (guests), `guest.custom` (guests), `user` (authenticated users). Not using Laravel's default `auth` middleware.