Files
website/CLAUDE.md
Claude Dev 2bf8a5b6bf docs: update README with current project status, optimize CLAUDE.md
README: reflect completed phases (1-5, 8-9), accurate tech stack
(Vuetify 3 not Tailwind, Passport not Sanctum, standalone tickets
not SupportPal), current codebase counts (59 migrations, 29 models,
85 pages, ~497 tests), and separate implemented vs planned features.

CLAUDE.md: reduce from 281 to 184 lines — trim derivable directory
listings, remove stale counts, cut redundant examples, update all
metrics to current state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:55:01 -04:00

9.4 KiB

CLAUDE.md - EZSCALE Site

Project

EZSCALE Site — Laravel 12 application for VPS/Dedicated Server hosting management (billing, subscriptions, provisioning, customer management, SSO).

Phase Tracking (MANDATORY)

All work MUST be tracked against GitHub issues and TASKS.md:

  1. Before starting: Check the relevant GitHub issue (gh issue list) and TASKS.md for current status.
  2. While working: Update the GitHub issue with progress comments (gh issue comment <number> --body "Completed X").
  3. After completing: Update TASKS.md to check off completed items and close the corresponding GitHub issue.
  4. New tasks discovered: Create sub-issues or add items to TASKS.md immediately.
  5. Commit messages: Reference the GitHub issue number (e.g., Fix checkout validation (#3)).

GitHub issues: https://github.com/EZSCALE/accounting/issues

Documentation Updates (MANDATORY)

When a phase or significant task is finished, update: TASKS.md, GitHub issues, CLAUDE.md, memory files, and PROJECT_DEVELOPMENT.md (if architecture changed).

Visual Verification (MANDATORY)

After every successful npm run build:

  1. Take headless Chrome screenshots of affected pages
  2. Compare against the EZSCALE design system (navy blue palette, Plus Jakarta Sans, custom SCSS in resources/styles/)
  3. Fix any visual discrepancies before considering the task complete
  4. Key pages: Login/Register, Marketing homepage, Admin/Account dashboards, Pricing page

Laravel App Location

The Laravel application is in website/. All artisan, composer, and npm commands run from there.

website/
├── app/
│   ├── Models/              # 29 Eloquent models
│   ├── Http/Controllers/    # Account/, Admin/, Api/V1/ controllers
│   ├── Http/Resources/      # API Resources
│   ├── Services/Billing/    # BillingServiceInterface, Stripe, PayPal, Dunning
│   ├── Events/              # Payment, Subscription events
│   ├── Listeners/           # Event handlers
│   └── Console/Commands/    # RetryProvisioning, SyncStripePrices
├── bootstrap/app.php        # Middleware, exceptions, routing (Laravel 12 slim — no Kernel files)
├── database/                # 59 migrations, 24 factories, seeders
├── resources/
│   ├── ts/                  # TypeScript source (Vue 3 + Inertia)
│   │   ├── types/           # Shared TypeScript interfaces
│   │   ├── Layouts/         # AccountLayout, AdminLayout, AuthLayout, MarketingLayout
│   │   ├── Components/      # Shared + marketing components
│   │   └── Pages/           # 85 Vue pages (Auth/7, Admin/41, Marketing/14, etc.)
│   └── styles/              # EZSCALE design system SCSS (8 files)
├── routes/                  # web, account, admin, marketing, webhooks, api
└── tests/                   # ~497 Pest tests

Tech Stack

  • Framework: Laravel 12 (PHP 8.3)
  • Frontend: Vue 3 + Inertia.js v2 + TypeScript (REQUIRED) + Vuetify 3 + Vite 7
  • UI Theme: Custom EZSCALE design system — navy blue #1d4ed8, Plus Jakarta Sans + JetBrains Mono (Bunny Fonts CDN), subdomain-aware theming (light for marketing, dark for admin/account)
  • Charts: ECharts via vue-echarts
  • Utilities: @vueuse/core
  • Testing: Pest 4 + PHPUnit 12 (~497 tests)
  • Formatting: Laravel Pint
  • Payments: Laravel Cashier (Stripe) + srmklive/paypal (PayPal)
  • Database: MySQL 8.x, database driver for sessions (Redis NOT installed)
  • Auth: Laravel Fortify (login, register, 2FA, password reset, email verify) + Passport (OAuth2/SSO)
  • Roles: spatie/laravel-permission (admin, customer)
  • Queue: Laravel Horizon

Commands

cd website
composer run dev               # Start all dev servers (artisan serve + queue + pail + vite)
php artisan test --compact     # Run Pest tests
npm run build                  # Production build
vendor/bin/pint --dirty --format agent  # Format changed files

TypeScript Requirement (MANDATORY)

All frontend code MUST use TypeScript.

  • All .vue files must use <script setup lang="ts"> (never plain <script setup>)
  • Props: interface Props + withDefaults(defineProps<Props>(), {...})
  • Emits: defineEmits<{ event: [payload: Type] }>()
  • Explicit types for ref<Type>(), computed<Type>(), and function return types
  • No any type — use proper interfaces or type aliases
  • Shared types go in resources/ts/types/
  • Inertia page props should be typed with interfaces

Design System

Colors

  • Primary: Navy blue #1d4ed8, lighter variant #3b82f6
  • Subdomain theming: Marketing = light mode, Admin/Account = dark mode by default
  • Theme persistence: localStorage key ezscale-theme, read on Vuetify init

Typography

  • UI font: Plus Jakarta Sans (Bunny Fonts CDN)
  • Code font: JetBrains Mono (Bunny Fonts CDN)

Key Patterns

  • Component ordering: <script lang="ts" setup> then props interface, state, computed, methods, watchers
  • Layout system: AppSidebar (collapsible) + AppTopNavbar (sticky) + CommandPalette (Cmd+K)
  • Navigation types: NavLink, NavGroup, NavSectionTitle (see resources/ts/@layouts/types.ts)
  • State management: Pinia stores (e.g., stores/toast.ts)
  • Icons: Tabler icons via @iconify/vue (e.g., tabler-smart-home)

Gotchas

  • User::billingInvoices() — renamed from invoices() to avoid conflict with Laravel Cashier's built-in invoices() method. All call sites use billingInvoices(). The withCount uses alias billing_invoices_count.

Agent Usage (MANDATORY)

Maximize use of subagents (Task tool) to reduce context usage. Main conversation should orchestrate; heavy lifting goes to agents.

  • Parallel agents: Launch independent tasks as parallel agents, not sequentially in main context.
  • Delegate research: Use Explore agents for codebase exploration and file searches.
  • Delegate implementation: Use general-purpose agents for self-contained tasks.
  • Delegate reviews: Use feature-dev:code-reviewer agents to review code after writing it.
  • Delegate architecture: Use feature-dev:code-architect or Plan agents for feature design.
  • Background agents: Use run_in_background: true for long-running tasks.
  • Batch similar work: 10+ file updates with the same pattern go to an agent.
  • Frontend Design Skill: ALWAYS run in background (run_in_background: true).

Headless Chrome

google-chrome --headless=new --disable-gpu --no-sandbox --screenshot=/tmp/screenshot.png --window-size=1920,1080 --virtual-time-budget=15000 "URL"
  • Must use --headless=new, --virtual-time-budget=15000, and --no-sandbox
  • dbus errors in output are harmless — ignore them
  • Read the resulting PNG with the Read tool to view it

Code Conventions

PHP

  • PSR-12, enforced by Pint
  • declare(strict_types=1); in all PHP files
  • Explicit return types and parameter type hints
  • PHP 8 constructor property promotion
  • Form Request classes for validation (not inline in controllers)
  • Service classes for business logic (thin controllers)
  • Events/Listeners for side effects (email, provisioning)
  • Eloquent over raw queries; avoid DB::, prefer Model::query()
  • Eager loading to prevent N+1 queries
  • config() only, never env() outside config files
  • Named routes with route() helper
  • Pest tests for all new functionality
  • Database transactions for multi-step operations
  • Check sibling files for conventions before creating new files
  • Run vendor/bin/pint --dirty --format agent before finalizing

Frontend (Vue/TypeScript)

  • Use Vuetify components directly (VCard, VBtn, VTextField, etc.) — not raw HTML
  • Use Inertia Link component for navigation (not <a> tags)
  • Use useForm() from @inertiajs/vue3 for form submissions
  • Status badges: VChip with resolveStatusColor() utilities
  • Pinia stores for shared state
  • ECharts via vue-echarts for charts

Security

  • All API endpoints require authentication
  • Admin routes protected by role-based middleware
  • CSRF on all forms (webhooks exempted via bootstrap/app.php)
  • Rate limiting on auth and API endpoints
  • Audit logging for admin actions and billing events

Domains

  • ezscale.dev (dev) / ezscale.cloud (prod) — marketing site
  • account.ezscale.dev / account.ezscale.cloud — customer dashboard
  • admin.ezscale.dev / admin.ezscale.cloud — admin panel (Cloudflare Zero Trust)
  • Subdomain routing configured in bootstrap/app.php via Route::domain()

Key Business Domains

  1. Billing — Subscriptions, invoices, payments (Stripe + PayPal), dunning, coupons
  2. Provisioning — VirtFusion (VPS), SynergyCP (Dedicated), Enhance (Hosting), Pterodactyl (Game) — idempotent with retry
  3. Customer Management — Profiles, support tickets, notifications
  4. Admin Panel — Dashboard, analytics, user/service management
  5. SSO — Single sign-on via Laravel Passport

Reference Docs

  • TASKS.md — Task list and progress tracking
  • PROJECT_DEVELOPMENT.md — Architecture decisions, database schema, API integrations
  • FEATURES.md — Feature specifications
  • ADVANCED_FEATURES.md — Advanced feature specs
  • KASM_AND_MULTITENANCY.md — Kasm Workspaces + reseller multi-tenancy
  • GETTING_STARTED.md — Development setup guide
  • docs/ — Deployment configs (deployment/), API specs (integrations/), scripts (scripts/), feature plans (superpowers/)
  • website/CLAUDE.md — Laravel Boost guidelines (auto-generated)