Files
portal-api/CLAUDE.md
T

175 lines
6.0 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Overview
Laravel 10 backend for a VPS/hosting SaaS platform. Provides an admin panel (Livewire), a customer REST API (JWT), and an admin REST API (JWT + Passport), with deep VMware vCenter integration for VM provisioning.
---
## Common Commands
```bash
# Dev server
php artisan serve
# Migrations & seeding
php artisan migrate
php artisan db:seed --class=SomeSeeder
# Clear all caches
php artisan cache:clear && php artisan config:clear && php artisan route:clear && php artisan view:clear
# Queue
php artisan queue:work
php artisan horizon
# Tests
php artisan test
php artisan test tests/Feature/SomeTest.php
php artisan test --filter testMethodName
# Swagger docs regeneration
php artisan l5-swagger:generate
```
---
## Routing
Four route files, each serving a different audience:
| File | Domain/Prefix | Auth | Audience |
|------|---------------|------|----------|
| `routes/admin.php` | `admin.portal.test` | Session (`auth` + `Staff`) | Admin panel web UI |
| `routes/api.php` | `/api/v1/administrator/` | JWT (`admins-api` guard) | Admin REST API |
| `routes/client.php` | `/api/v1/client/` | JWT (`client` guard) | Customer REST API |
| `routes/web.php` | `/` | None | Public pages |
**Middleware aliases:**
- `Staff` → `StaffCheck` — enforces admin session, updates `last_visited`
- `api.auth` → `ApiAuthCheck` — JWT validation, returns JSON 401 on failure
- `LoginCheck` — redirects authenticated users away from login page
---
## Architecture
### Controller Layers
```
app/Http/Controllers/
├── admin/ — Admin panel web controllers (Blade/Livewire views)
├── Api/Admin/ — Admin REST API controllers
├── Api/Client/ — Customer REST API (ClientController)
├── Api/Service/ — Product/order/service endpoints (used by both)
├── Api/Transaction/— Payment and transaction endpoints
└── rest/ — Legacy internal REST endpoints
```
### Repository Pattern
All DB access goes through repositories. Never query models directly in controllers.
```
app/Repositories/{Domain}/
├── {Domain}Repository.php — Concrete (extends BaseRepository)
├── {Domain}RepositoryInterface.php — Interface
└── {Domain}CachedRepository.php — Redis-cached variant (optional)
```
**BaseRepository** provides: `create`, `update`, `delete`, `find`, `getAll`, `getCount`, `insert`.
Repositories are bound in `AppServiceProvider` → `RepositoryProvider` (40+ bindings). Always inject via interface.
### Service Layer
Business logic is split across two locations:
- `app/Services/` — Domain services: `VMDataService`, `VMHelperService`, `WhoisService`
- `app/Http/Services/` — HTTP-integration services:
- `vCenter.php` — VMware vCenter REST API wrapper (Guzzle, SSL disabled for self-signed certs). Key methods: `loginServer()`, `GetConsoleTickets()`, `getAllVirtualMachine()`, `checkApiExits()`. Token stored in model, refreshed on 'Login_Again' response.
- `WinRMClient.php` — Windows Remote Management for VM operations
- `VNPayService.php` — Payment gateway
- `Invoice/` — Invoice generation/processing
- `PusherNotification.php`, `Telegram.php`, `Discord.php` — Notifications
Dedicated admin service layer: `app/Services/Api/Admin/` (`ProductService`, `VCenterService`), `app/Services/Api/` (`ClientAuthService`, `ServiceService`).
### Global Helpers
`app/Http/Helpers/function_helper.php` (auto-loaded via Composer):
- `setting('group.key')` — Read cached settings with dot notation
- `format_price(amount)` — Format as ₫ currency
- `format_point(points)` — Format loyalty points
- `format_day(date, format)` — Date formatting
### Enums
Type-safe PHP enums in `app/Enums/{Domain}/`. Support `label()` for Vietnamese display text. Key enums: `InvoiceStatus`, `ProductTypeEnums`, `TransactionStatus`, `Status`, `AddonType`.
### Admin UI
Livewire 3 components in `app/Http/Livewire/`. Modal pattern uses Alpine.js events:
- Open: `$dispatch('open-{modal-name}')` / listen with `@open-{modal-name}.window`
- Close: `$dispatch('close-{modal-name}')` / listen with `@close-{modal-name}.window`
Server-side tables use Yajra DataTables.
---
## Auth Guards
| Guard | Driver | Used By |
|-------|--------|---------|
| `web` / `admins` | session | Admin panel |
| `admins-api` | JWT (tymon/jwt-auth) | Admin REST API |
| `client` | JWT (tymon/jwt-auth) | Customer API (portal-client) |
| `users-api` | Passport OAuth2 | — |
| `client-sanctum` | Sanctum | Alternative customer auth |
---
## Key Models
**Core business:** `Customer` (UUID PK, JWT subject), `Order`, `Invoice` (InvoiceStatus enum), `InvoiceItem`, `Product` (slug, cpu/ram/disk/bandwidth/gpu specs), `ProductCategories` (hierarchical via kalnoy/nestedset).
**VMware:** `vCenter` (credentials + token), `ModuleVmware` (VM instances → orders), `ModuleHost`, `ModuleDatacenter`, `ModuleNetwork`, `ModuleIpAddress`, `ModuleDatastore`, `ModuleSnapshot`.
**Finance:** `Transaction`, `Payment`, `Cart`, `CartAddon`.
**Support:** `Ticket`, `TicketReply`, `Mail`.
---
## Queue Jobs
Async operations in `app/Jobs/`:
- `VirtualMachine/ProcessOrderPaymentJob` — Payment processing + VM provisioning
- `Hosting/`, `Mail/`, `Ticket/`, `Payment/` — Domain-specific async tasks
---
## API Response Convention
```json
{ "error": false, "data": {...} }
{ "error": true, "message": "Reason here" }
```
API Resources in `app/Http/Resources/Api/` transform models before response.
---
## Key Integrations
- **VMware vCenter** — `app/Http/Services/vCenter.php`, passwords decrypted via `SignRSA` facade
- **VNPay** — `config/vnpay.php`, `VNPayService.php`
- **Redis** — Caching (cached repositories), sessions, queues
- **Pusher** — Real-time events
- **CKFinder** — Admin file browser (custom auth: `CustomCKFinderAuth` middleware)
- **L5-Swagger** — API docs at `/api/documentation`
- **Spatie Permission** — RBAC for admin roles
- **Horizon** — Queue monitoring at `/horizon`