311 lines
16 KiB
Markdown
311 lines
16 KiB
Markdown
<laravel-boost-guidelines>
|
|
=== .ai/xinadmin rules ===
|
|
|
|
# XinAdmin
|
|
|
|
XinAdmin is a full-stack development framework: PHP8.2 + Laravel12 + React19 + TypeScript + Ant Design6 + Zustand + Tailwind CSS4. Licensed under MIT, free for commercial use without authorization.
|
|
|
|
## Built-in Features
|
|
|
|
- Dashboard: Echarts-based dashboards with demo pages
|
|
- Administrators: Backend user management with groups, permissions, and settings
|
|
- Role & Department Management: Role-based menu permission control, enterprise org structure
|
|
- System Settings: Visual form-based server variable configuration
|
|
- File Management: Backend file manager with folders, multi-select, grouping
|
|
- Dictionary Management: Maintenance of frequently used static data
|
|
- Mail & Storage Configuration: Visual config and testing for Laravel mail/filesystem
|
|
- AI Configuration: Visual config and testing for Laravel AI SDK
|
|
- Frontend Members: Permission, grouping, lists, balance records
|
|
|
|
# AnnoRoute
|
|
|
|
AnnoRoute is a PHP 8 Attribute-based route registration module. Routes are declared via controller annotations — no manual route files needed. Sanctum auth and permission verification are auto-integrated.
|
|
|
|
## Usage
|
|
|
|
- `#[GetRoute]` / `#[PostRoute]` / `#[PutRoute]` / `#[DeleteRoute]` on methods declare HTTP routes
|
|
- The `authorize` parameter controls access: `'query'` becomes ability `prefix.query`, `false` makes a route public
|
|
- `#[RequestAttribute]` params: `routePrefix`, `abilitiesPrefix`, `middleware` (string|array), `authGuard` (?string)
|
|
- Method attributes share: `route` (path appended to prefix), `authorize` (string|bool), `middleware`, `where` (regex array)
|
|
- Final route = `routePrefix + route`; final ability = `abilitiesPrefix + '.' + authorize`
|
|
- When `authorize` is not falsy, `auth:sanctum` + `authGuard` + `abilities:` middleware are auto-assembled
|
|
- Extend `Modules\Common\Http\Controllers\BaseController` for `success()` / `error()` response helpers
|
|
|
|
# Frontend
|
|
|
|
Source lives in `web/`. Bundled with Vite, outputting to `public/`. Package manager: pnpm.
|
|
|
|
## Directory Structure
|
|
|
|
| Directory | Purpose |
|
|
|-----------|---------|
|
|
| `web/api/` | Typed Axios wrappers per backend module |
|
|
| `web/components/` | Reusable UI: `AuthButton`, `DictTag`, `IconFont`, `XinForm`, `XinTable` |
|
|
| `web/domain/` | TypeScript interfaces for API models |
|
|
| `web/hooks/` | `useAuth`, `useLanguage`, `useMobile`, `useRequest` |
|
|
| `web/layout/` | Layout engine (4 modes), menu, header, breadcrumbs, theme |
|
|
| `web/locales/` | i18n (i18next), zh_CN + en_US |
|
|
| `web/pages/` | Auto-discovered page components (file-system routing) |
|
|
| `web/router/` | React Router v7 `createBrowserRouter` |
|
|
| `web/stores/` | Zustand: `global` (app/theme), `user` (auth/perms), `dict` (cache) |
|
|
| `web/utils/` | Axios instance with dedup, auth headers, error handling |
|
|
|
|
## Key Conventions
|
|
|
|
- Path alias `@/` → `web/`
|
|
- Zustand stores: `State` + `Actions` → `persist` + `devtools` → localStorage
|
|
- Access stores via selector: `useXxxStore(state => state.field)`
|
|
- All user-facing text via `useTranslation()` (react-i18next)
|
|
- Locale files mirror page paths: `pages/system/user.tsx` → `locales/zh_CN/system/user.ts`, key prefix `system.user`
|
|
- All keys dot-separated, double quotes, 2-space indent. See `@skill:xinadmin-development` for details
|
|
- Permission checks: `<AuthButton auth="system.user.create">` or `useAuth().auth('permission')`
|
|
- HTTP client auto-attaches `Authorization: Bearer`, `User-Language`, handles 401 auto-logout
|
|
- Pages in `web/pages/` are auto-routed; `index.tsx` maps to parent directory; root `/` → `/dashboard/analysis`
|
|
- Pages outside layout: add to `excludePaths` array in router config
|
|
|
|
# Antd
|
|
|
|
Ant Design 6 is the UI component library. Components are imported from `antd` and themed via `<ConfigProvider>` with tokens from `web/layout/theme.ts`.
|
|
|
|
## Key Conventions
|
|
|
|
- Use `antd` MCP tools (`antd_info`, `antd_doc`, `antd_demo`) to verify component APIs before writing code
|
|
- Never use deprecated props or components — check with `antd_changelog` when upgrading or referencing older examples
|
|
- Theme tokens flow: `web/layout/theme.ts` → `<ConfigProvider theme={...}>` → Ant Design components
|
|
- Common components: `Table`, `Form`, `Modal`, `Drawer`, `Button`, `Input`, `Select`, `DatePicker`, `Switch`, `Tag`, `Card`, `App` ...
|
|
|
|
# Layout
|
|
|
|
Wraps authenticated pages. Supports 4 modes set via global store: `side` (default), `top`, `mix`, `columns`.
|
|
|
|
Menus are fetched from `/system/menu` and stored in `LayoutContext` (React Context). Menu type: `'menu'` (folder), `'route'` (page), `'rule'` (perm-only). Server filters by user role — no client-side filtering needed. Labels support i18n via `node.local`.
|
|
|
|
Theme tokens (20+ properties) are managed in `web/layout/theme.ts`, applied via Ant Design `<ConfigProvider>`, persisted to localStorage under `global-storage`.
|
|
|
|
# XinForm And XinTable
|
|
|
|
Two declarative JSON-driven CRUD components. Define columns once with metadata — the same definition drives table display, search form, and create/edit forms.
|
|
|
|
## XinForm
|
|
|
|
Use for settings/config pages or standalone forms. Supports 3 layout modes: `'Form'` (inline), `'ModalForm'`, `'DrawerForm'`.
|
|
|
|
```tsx
|
|
<XinForm
|
|
columns={[
|
|
{ dataIndex: 'username', title: 'Username', valueType: 'text', rules: [{ required: true }] },
|
|
{ dataIndex: 'role_id', title: 'Role', valueType: 'select', fieldProps: { options: roleOptions } },
|
|
]}
|
|
layoutType="ModalForm"
|
|
grid
|
|
trigger={<Button type="primary">New</Button>}
|
|
modalProps={{ title: 'Create User', width: 600 }}
|
|
onFinish={async (values) => { await save(values); return true; }}
|
|
/>
|
|
```
|
|
|
|
Key `FormColumn` fields: `dataIndex` (supports nested paths `['a','b']`), `valueType` (26 types: `text`, `password`, `select`, `date`, `switch`, etc.), `fieldProps`, `fieldRender` (custom render), `dependency` (field linkage: `{ dependencies, visible?, disabled?, fieldProps? }`), `hideIn*` visibility flags.
|
|
|
|
`formRef` exposes `open()`, `close()`, `isOpen()`, `setLoading()` plus all Ant Design `FormInstance` methods.
|
|
|
|
## XinTable
|
|
|
|
Use for standard CRUD pages (list + create + update + delete). Auto-handles API calls, permissions, search, and toolbar.
|
|
|
|
```tsx
|
|
<XinTable<ISysUser>
|
|
api="/system/user"
|
|
columns={[
|
|
{ title: 'ID', dataIndex: 'id', hideInForm: true, width: 80 },
|
|
{ title: 'Username', dataIndex: 'username', valueType: 'text', rules: [{ required: true }] },
|
|
{ title: 'Status', dataIndex: 'status', valueType: 'radio', render: (v) => <Tag>{v === 1 ? 'Active' : 'Inactive'}</Tag> },
|
|
]}
|
|
rowKey="id"
|
|
accessName="system.user"
|
|
formProps={{ grid: true, colProps: { span: 12 }, layout: 'vertical' }}
|
|
modalProps={{ width: 800 }}
|
|
/>
|
|
```
|
|
|
|
Required props: `api` (REST endpoint), `accessName` (permission prefix), `rowKey` (PK field), `columns`.
|
|
|
|
Default REST behavior — `GET {api}` for list, `POST {api}` for create, `PUT {api}/{id}` for update, `DELETE {api}/{id}` for delete. Add/edit/delete buttons auto-wrapped in `<AuthButton auth={accessName + '.create'}>`.
|
|
|
|
Customize with: `handleRequest` (full custom fetch), `requestParams` (transform before send), `handleFinish` (custom submit), `actionBarRender` / `toolBarRender` / `operateRender` (slot overrides).
|
|
|
|
## Choosing Between Them
|
|
|
|
- **XinTable**: Full CRUD pages (users, roles, dicts, files)
|
|
- **XinForm** (inline/ModalForm): Settings pages with a single form (mail, storage, AI config)
|
|
- **XinForm** (ModalForm + trigger): Add/edit without a table (dept management)
|
|
- Use `hideInForm` / `hideInTable` / `hideInSearch` to control per-context visibility
|
|
|
|
# Development Workflow
|
|
|
|
When building a new CRUD feature, follow this four-phase workflow. See `@skill:xinadmin-development` for complete details.
|
|
|
|
1. **Database Migration** — create table structure, indexes, foreign keys
|
|
2. **Backend** — Controller (AnnoRoute attributes), Model, FormRequest
|
|
3. **Frontend** — Page (file-system routing), Domain types, API wrappers, i18n
|
|
4. **Menu & Permissions** — seeder menu entry + rules, menu translation keys
|
|
|
|
=== foundation rules ===
|
|
|
|
# Laravel Boost Guidelines
|
|
|
|
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when building Laravel applications.
|
|
|
|
## Foundational Context
|
|
|
|
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
|
|
|
|
- php - 8.3
|
|
- laravel/ai (AI) - v0
|
|
- laravel/framework (LARAVEL) - v13
|
|
- laravel/prompts (PROMPTS) - v0
|
|
- laravel/sanctum (SANCTUM) - v4
|
|
- laravel/boost (BOOST) - v2
|
|
- laravel/mcp (MCP) - v0
|
|
- laravel/pail (PAIL) - v1
|
|
- laravel/sail (SAIL) - v1
|
|
- phpunit/phpunit (PHPUNIT) - v12
|
|
- react (REACT) - v19
|
|
- eslint (ESLINT) - v9
|
|
- tailwindcss (TAILWINDCSS) - v4
|
|
|
|
## Skills Activation
|
|
|
|
This project has domain-specific skills available in `**/skills/**`. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.
|
|
|
|
## Conventions
|
|
|
|
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming.
|
|
- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
|
|
- Check for existing components to reuse before writing a new one.
|
|
|
|
## Verification Scripts
|
|
|
|
- Do not create verification scripts or tinker when tests cover that functionality and prove they work. Unit and feature tests are more important.
|
|
|
|
## Application Structure & Architecture
|
|
|
|
- Stick to existing directory structure; don't create new base folders without approval.
|
|
- Do not change the application's dependencies without approval.
|
|
|
|
## Frontend Bundling
|
|
|
|
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `pnpm run build`, `pnpm run dev`, or `composer run dev`. Ask them.
|
|
|
|
## Documentation Files
|
|
|
|
- You must only create documentation files if explicitly requested by the user.
|
|
|
|
## Replies
|
|
|
|
- Be concise in your explanations - focus on what's important rather than explaining obvious details.
|
|
|
|
=== boost rules ===
|
|
|
|
# Laravel Boost
|
|
|
|
## Tools
|
|
|
|
- Laravel Boost is an MCP server with tools designed specifically for this application. Prefer Boost tools over manual alternatives like shell commands or file reads.
|
|
- Use `database-query` to run read-only queries against the database instead of writing raw SQL in tinker.
|
|
- Use `database-schema` to inspect table structure before writing migrations or models.
|
|
- Use `get-absolute-url` to resolve the correct scheme, domain, and port for project URLs. Always use this before sharing a URL with the user.
|
|
- Use `browser-logs` to read browser logs, errors, and exceptions. Only recent logs are useful, ignore old entries.
|
|
|
|
## Searching Documentation (IMPORTANT)
|
|
|
|
- Always use `search-docs` before making code changes. Do not skip this step. It returns version-specific docs based on installed packages automatically.
|
|
- Pass a `packages` array to scope results when you know which packages are relevant.
|
|
- Use multiple broad, topic-based queries: `['rate limiting', 'routing rate limiting', 'routing']`. Expect the most relevant results first.
|
|
- Do not add package names to queries because package info is already shared. Use `test resource table`, not `filament 4 test resource table`.
|
|
|
|
### Search Syntax
|
|
|
|
1. Use words for auto-stemmed AND logic: `rate limit` matches both "rate" AND "limit".
|
|
2. Use `"quoted phrases"` for exact position matching: `"infinite scroll"` requires adjacent words in order.
|
|
3. Combine words and phrases for mixed queries: `middleware "rate limit"`.
|
|
4. Use multiple queries for OR logic: `queries=["authentication", "middleware"]`.
|
|
|
|
## Artisan
|
|
|
|
- Run Artisan commands directly via the command line (e.g., `php artisan route:list`). Use `php artisan list` to discover available commands and `php artisan [command] --help` to check parameters.
|
|
- Inspect routes with `php artisan route:list`. Filter with: `--method=GET`, `--name=users`, `--path=api`, `--except-vendor`, `--only-vendor`.
|
|
- Read configuration values using dot notation: `php artisan config:show app.name`, `php artisan config:show database.default`. Or read config files directly from the `config/` directory.
|
|
|
|
## Tinker
|
|
|
|
- Execute PHP in app context for debugging and testing code. Do not create models without user approval, prefer tests with factories instead. Prefer existing Artisan commands over custom tinker code.
|
|
- Always use single quotes to prevent shell expansion: `php artisan tinker --execute 'Your::code();'`
|
|
- Double quotes for PHP strings inside: `php artisan tinker --execute 'User::where("active", true)->count();'`
|
|
|
|
=== php rules ===
|
|
|
|
# PHP
|
|
|
|
- Always use curly braces for control structures, even for single-line bodies.
|
|
- Use PHP 8 constructor property promotion: `public function __construct(public GitHub $github) { }`. Do not leave empty zero-parameter `__construct()` methods unless the constructor is private.
|
|
- Use explicit return type declarations and type hints for all method parameters: `function isAccessible(User $user, ?string $path = null): bool`
|
|
- Use TitleCase for Enum keys: `FavoritePerson`, `BestLake`, `Monthly`.
|
|
- Prefer PHPDoc blocks over inline comments. Only add inline comments for exceptionally complex logic.
|
|
- Use array shape type definitions in PHPDoc blocks.
|
|
|
|
=== deployments rules ===
|
|
|
|
# Deployment
|
|
|
|
- Laravel can be deployed using [Laravel Cloud](https://cloud.laravel.com/), which is the fastest way to deploy and scale production Laravel applications.
|
|
|
|
=== laravel/core rules ===
|
|
|
|
# Do Things the Laravel Way
|
|
|
|
- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using `php artisan list` and check their parameters with `php artisan [command] --help`.
|
|
- If you're creating a generic PHP class, use `php artisan make:class`.
|
|
- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior.
|
|
|
|
### Model Creation
|
|
|
|
- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `php artisan make:model --help` to check the available options.
|
|
|
|
## APIs & Eloquent Resources
|
|
|
|
- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention.
|
|
|
|
## URL Generation
|
|
|
|
- When generating links to other pages, prefer named routes and the `route()` function.
|
|
|
|
## Testing
|
|
|
|
- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model.
|
|
- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`.
|
|
- When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests.
|
|
|
|
## Vite Error
|
|
|
|
- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `pnpm run build` or ask the user to run `pnpm run dev` or `composer run dev`.
|
|
|
|
=== phpunit/core rules ===
|
|
|
|
# PHPUnit
|
|
|
|
- This application uses PHPUnit for testing. All tests must be written as PHPUnit classes. Use `php artisan make:test --phpunit {name}` to create a new test.
|
|
- If you see a test using "Pest", convert it to PHPUnit.
|
|
- Every time a test has been updated, run that singular test.
|
|
- When the tests relating to your feature are passing, ask the user if they would like to also run the entire test suite to make sure everything is still passing.
|
|
- Tests should cover all happy paths, failure paths, and edge cases.
|
|
- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files; these are core to the application.
|
|
|
|
## Running Tests
|
|
|
|
- Run the minimal number of tests, using an appropriate filter, before finalizing.
|
|
- To run all tests: `php artisan test --compact`.
|
|
- To run all tests in a file: `php artisan test --compact tests/Feature/ExampleTest.php`.
|
|
- To filter on a particular test name: `php artisan test --compact --filter=testName` (recommended after making a change to a related file).
|
|
|
|
</laravel-boost-guidelines>
|