Update CLAUDE.md with mandatory phase tracking rules (GitHub issues + TASKS.md), TypeScript requirement for all frontend code, Vuexy theme reference, and updated project structure reflecting Phase 1-2 completion. Add comprehensive CLAUDE.md to Vuexy theme directory documenting components, patterns, and conventions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10 KiB
CLAUDE.md - EZSCALE Site
Project
EZSCALE Site — Laravel 12 application replacing WHMCS 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:
- Before starting any phase work: Check the relevant GitHub issue (see
gh issue list) andTASKS.mdfor current status. - While working: Update the GitHub issue with progress comments as significant milestones are completed (e.g.,
gh issue comment <number> --body "Completed X"). - After completing work: Update
TASKS.mdto check off completed items and close/update the corresponding GitHub issue. - New tasks discovered during work: Create sub-issues or add items to
TASKS.mdimmediately. - Commit messages: Reference the GitHub issue number (e.g.,
Fix checkout validation (#3)).
GitHub issues: https://github.com/EZSCALE/accounting/issues
Laravel App Location
The Laravel application is in website/. All artisan, composer, and npm commands run from there.
website/
├── app/
│ ├── Models/ # 14 Eloquent models
│ ├── Http/Controllers/ # Account/ and Admin/ controllers
│ ├── Services/Billing/ # BillingServiceInterface, Stripe, PayPal, Dunning
│ ├── Events/ # PaymentSucceeded/Failed, SubscriptionCreated/Cancelled
│ ├── Listeners/ # HandlePaymentSucceeded/Failed
│ └── Providers/ # AppServiceProvider, FortifyServiceProvider
├── bootstrap/app.php # Middleware, exceptions, routing (Laravel 12 style)
├── config/ # App, auth, fortify, passport, cashier, paypal, permission
├── database/
│ ├── migrations/ # 30 migrations (15 custom + defaults + packages)
│ ├── factories/ # 7 factories
│ └── seeders/ # Roles, plans, admin user
├── resources/
│ ├── js/ # Vue 3 + Inertia pages (TO BE MIGRATED TO TypeScript)
│ │ ├── Layouts/ # AppLayout, AuthLayout, AdminLayout
│ │ ├── Pages/ # Auth/, Billing/, Plans/, Subscriptions/, Admin/
│ │ └── Components/ # Card, Button, NavLink, FlashMessages
│ ├── css/app.css # Tailwind CSS 4
│ └── views/app.blade.php # Inertia root template
├── routes/ # web.php, account.php, admin.php, marketing.php, webhooks.php, api.php
├── tests/ # 53 Pest tests (Phase 1 + Phase 2)
├── composer.json
├── package.json
└── vite.config.js
Tech Stack
- Framework: Laravel 12 (PHP 8.3), Laravel 12 slim structure (no Kernel files)
- Frontend: Vue 3 + Inertia.js v2 + TypeScript (REQUIRED) + Tailwind CSS 4 + Vite 7
- UI Theme: Vuexy Vue + Laravel Admin Dashboard (reference at
../vuexy-theme-vue-laravel-full-example-typescript/) - Testing: Pest 4 + PHPUnit 12
- Formatting: Laravel Pint
- Payments: Laravel Cashier (Stripe) + srmklive/paypal (PayPal)
- Database: MySQL 8.x, Redis for cache/queue/sessions
- Auth: Laravel Fortify (login, register, 2FA, password reset, email verify) + Passport (OAuth2/SSO)
- Roles: spatie/laravel-permission (admin, customer)
Commands
cd website
composer run dev # Start all dev servers (artisan serve + queue + pail + vite)
php artisan serve # Laravel dev server only
php artisan test --compact # Run Pest tests
php artisan migrate # Run migrations
npm run dev # Vite dev server only
npm run build # Production build
vendor/bin/pint --dirty --format agent # Format changed files
TypeScript Requirement (MANDATORY)
All frontend code MUST use TypeScript. This applies to all Vue components, composables, utilities, and type definitions.
Rules
- All
.vuefiles must use<script setup lang="ts">(never plain<script setup>) - Define component props with
interface PropsandwithDefaults(defineProps<Props>(), {...}) - Define emits with typed
defineEmits<{ event: [payload: Type] }>() - Use explicit types for
ref<Type>(),computed<Type>(), and function return types - No
anytype — use proper interfaces or type aliases - Shared types go in
resources/js/types/(e.g.,models.ts,billing.ts) - Inertia page props should be typed with interfaces
Example Component Pattern
<script setup lang="ts">
import { Link } from '@inertiajs/vue3'
import AppLayout from '@/Layouts/AppLayout.vue'
interface Props {
title: string
items: Item[]
count?: number
}
interface Item {
id: number
name: string
status: 'active' | 'inactive'
}
defineOptions({ layout: AppLayout })
const props = withDefaults(defineProps<Props>(), {
count: 0,
})
const isActive = computed<boolean>(() => props.count > 0)
</script>
Migration Note
Existing .vue files in resources/js/ were written in plain JavaScript during Phase 1-2. They must be migrated to TypeScript as they are touched. When working on a page, convert it to TypeScript as part of the work.
Vuexy Theme Reference
The Vuexy theme is at ../vuexy-theme-vue-laravel-full-example-typescript/. Use it as a reference for UI patterns, component design, and styling conventions.
Key Vuexy Patterns to Follow
- Component structure:
<script lang="ts" setup>→ props interface → state → computed → methods → watchers - Vuetify components: VCard, VBtn, VTextField, VIcon, VAvatar, VChip, VDataTable, etc.
- Layout system: Vertical nav with collapsible sidebar, sticky navbar, configurable footer
- Theme system: Light/dark/system modes with skin variants (default, bordered)
- Navigation types:
NavLink,NavGroup,NavSectionTitle(seeresources/ts/@layouts/types.ts) - Composables: Reusable logic in
composables/directory (e.g.,useApi.ts) - State management: Pinia stores for shared state
- Icons: Tabler icons via
@iconify/vue(e.g.,tabler-smart-home,tabler-chart-bar)
Vuexy Directory Reference
vuexy-theme-vue-laravel-full-example-typescript/
├── resources/ts/ # TypeScript source
│ ├── @core/ # Core utilities, composables, components
│ ├── @layouts/ # Layout system (vertical/horizontal nav)
│ ├── layouts/ # Page layout templates (default, blank)
│ ├── pages/ # File-based routing pages
│ ├── plugins/ # Vue plugins (router, pinia, vuetify, i18n, casl)
│ ├── navigation/ # Nav item definitions (vertical/, horizontal/)
│ └── composables/ # App-level composables
├── resources/styles/ # SCSS with Vuetify variable overrides
├── themeConfig.ts # Global theme configuration
├── vite.config.ts # Vite with auto-import, file-based routing
└── tsconfig.json # Strict TypeScript config
Code Conventions
PHP
- PSR-12 coding standards, enforced by Pint
declare(strict_types=1);in all PHP files- Explicit return types and parameter type hints on all methods
- PHP 8 constructor property promotion
- Form Request classes for validation (not inline in controllers)
- Service classes for business logic (controllers stay thin)
- Policies for authorization
- Events/Listeners for side effects (email, provisioning, etc.)
- Eloquent models and relationships over raw DB queries; avoid
DB::, preferModel::query() - Eager loading to prevent N+1 queries
config()helper only, neverenv()outside config files- Named routes with
route()helper for URL generation - Feature and Unit tests (Pest) 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 agentbefore finalizing changes
Frontend (Vue/TypeScript)
- All components use
<script setup lang="ts"> - Props defined via
interface Props+defineProps<Props>() - Dark mode is the default UI theme (
bg-gray-950pages,bg-gray-900cards,bg-gray-800inputs) - Use Inertia
Linkcomponent for navigation (not<a>tags for internal links) - Use
useForm()from@inertiajs/vue3for form submissions - Status badges use semi-transparent colored backgrounds (e.g.,
bg-green-900/50 text-green-300) - Refer to Vuexy theme components and patterns when building new UI
Security
- All API endpoints require authentication
- Admin routes protected by role-based middleware
- CSRF protection on all forms (webhooks exempted via
bootstrap/app.php) - Rate limiting on auth and API endpoints
- Encrypted storage for sensitive data (API keys, credentials)
- Audit logging for admin actions and billing events
Domains
- ezscale.dev → ezscale.cloud (marketing site) — dev uses
.dev, production will use.cloud - 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.phpviaRoute::domain()
Key Business Domains
- Billing — Subscriptions, invoices, payments (Stripe + PayPal), dunning, coupons
- Provisioning — VirtFusion (VPS), Pterodactyl (Game), SynergyCP (Dedicated), Enhance (Hosting)
- Customer Management — Profiles, support tickets, notifications
- Admin Panel — Dashboard, analytics, user/service management
- SSO — Single sign-on via Laravel Passport
Reference Docs
TASKS.md— Task list and progress tracking (update after each phase)PROJECT_DEVELOPMENT.md— Architecture decisions, database schema, API integrationsFEATURES.md— Feature specifications (35+ features)ADVANCED_FEATURES.md— Advanced feature specs (28 features)KASM_AND_MULTITENANCY.md— Kasm Workspaces + reseller multi-tenancyGETTING_STARTED.md— Development setup guideIDEAS.md— Future feature ideaswebsite/CLAUDE.md— Laravel Boost guidelines (auto-generated, Laravel/Pest/Pint conventions)vuexy-theme-vue-laravel-full-example-typescript/— Vuexy theme reference (TypeScript, Vuetify, layouts)