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

184 lines
9.4 KiB
Markdown

# 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
```bash
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
```bash
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)