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>
9.4 KiB
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:
- Before starting: Check the relevant GitHub issue (
gh issue list) andTASKS.mdfor current status. - While working: Update the GitHub issue with progress comments (
gh issue comment <number> --body "Completed X"). - After completing: Update
TASKS.mdto check off completed items and close the corresponding GitHub issue. - New tasks discovered: 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
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:
- Take headless Chrome screenshots of affected pages
- Compare against the EZSCALE design system (navy blue palette, Plus Jakarta Sans, custom SCSS in
resources/styles/) - Fix any visual discrepancies before considering the task complete
- 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
.vuefiles 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
anytype — 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(seeresources/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-ininvoices()method. All call sites usebillingInvoices(). ThewithCountuses aliasbilling_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
Exploreagents for codebase exploration and file searches. - Delegate implementation: Use
general-purposeagents for self-contained tasks. - Delegate reviews: Use
feature-dev:code-revieweragents to review code after writing it. - Delegate architecture: Use
feature-dev:code-architectorPlanagents for feature design. - Background agents: Use
run_in_background: truefor 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::, preferModel::query() - Eager loading to prevent N+1 queries
config()only, neverenv()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 agentbefore finalizing
Frontend (Vue/TypeScript)
- Use Vuetify components directly (VCard, VBtn, VTextField, etc.) — not raw HTML
- Use Inertia
Linkcomponent for navigation (not<a>tags) - Use
useForm()from@inertiajs/vue3for form submissions - Status badges: VChip with
resolveStatusColor()utilities - Pinia stores for shared state
- ECharts via
vue-echartsfor 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.phpviaRoute::domain()
Key Business Domains
- Billing — Subscriptions, invoices, payments (Stripe + PayPal), dunning, coupons
- Provisioning — VirtFusion (VPS), SynergyCP (Dedicated), Enhance (Hosting), Pterodactyl (Game) — idempotent with retry
- 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 trackingPROJECT_DEVELOPMENT.md— Architecture decisions, database schema, API integrationsFEATURES.md— Feature specificationsADVANCED_FEATURES.md— Advanced feature specsKASM_AND_MULTITENANCY.md— Kasm Workspaces + reseller multi-tenancyGETTING_STARTED.md— Development setup guidedocs/— Deployment configs (deployment/), API specs (integrations/), scripts (scripts/), feature plans (superpowers/)website/CLAUDE.md— Laravel Boost guidelines (auto-generated)