# Parts Platform Administrator Guide

Last updated: 2026-07-03

This guide explains how to operate the Parts Platform from the custom admin panel. It reflects the current system: Laravel 13, React, Inertia, Tailwind CSS, Sanctum API tokens, dynamic product attributes, vehicle variants, product fitments, blog publishing, AI content suggestions, orders, customers, and webhooks.

## 1. Admin Access

The admin panel is available at:

```text
/admin
```

If you are not signed in, `/admin` redirects to:

```text
/admin/login
```

Only users with the `admin` role can sign in through the admin login screen.

To create or promote an admin account from the command line, use:

```bash
php artisan parts:make-admin admin@example.com --name="Parts Administrator" --password="secure-password"
```

To reset the password for an existing admin account:

```bash
php artisan parts:make-admin admin@example.com --password="new-secure-password" --reset-password
```

Seeded local development accounts, when seeders are run, are:

```text
admin@parts.local / password
user@parts.local / password
```

Use seeded credentials only in local development.

## 2. Admin Navigation

The admin panel is organized into these sections:

| Section | Pages |
| --- | --- |
| Overview | Dashboard |
| Catalog | Categories, Products, Orders, Customers |
| Vehicles | Brands, Manufacturers, Generations, Models, Engines, Gearboxes, Fuel Types, Body Styles, Drive Trains, Vehicle Variants |
| Metadata | Attribute Groups, Attributes |
| Blog | Articles, Categories, Tags, AI Content |
| Webhooks & APIs | API Tokens, Webhook Endpoints, Webhook Logs |
| Storefront | Public Storefront |

Most list pages include search, pagination, create, edit, delete, and active/inactive controls where the record type supports them.

Customer-facing account pages are separate from the admin panel. Customers use `/login`, `/register`, `/checkout`, and `/account/orders`; admins use `/admin/login` and `/admin`.

## 3. Important Data Rules

Products are the center of the platform. Every product should be entered with enough technical detail to support purchasing, SEO, reference search, and compatibility decisions.

Do not create fixed technical fields such as `pin_count`, `voltage`, or `connector_type` in the database. Technical specifications must be created as dynamic attributes under Metadata.

The vehicle catalog is first-class data. Create vehicle records carefully because product compatibility depends on vehicle variants and product fitments.

The system includes protected "Unknown" system records for categories, products, attributes, fuel types, body styles, drive trains, vehicle makes, vehicle models, vehicle generations, vehicle engines, gearboxes, and vehicle variants. These records cannot be edited or deleted like normal records. They can only have their active state changed where the admin exposes active-state controls.

AI content is always draft material. It must be reviewed by a human before it is applied, and applying AI content never publishes an article automatically.

The default commerce currency is `EUR`. Product prices are entered in EUR major units, and order totals are stored internally as minor units. Operators can override the default currency with:

```env
PARTS_DEFAULT_CURRENCY=EUR
```

## 4. Recommended Setup Order

Use this order when building catalog data from scratch:

1. Create base catalog categories.
2. Create attribute groups.
3. Create dynamic attributes.
4. Create vehicle base data: fuel types, body styles, drive trains.
5. Create manufacturers when engines or gearboxes need a producer.
6. Create vehicle brands, models, generations, engines, and gearboxes.
7. Create vehicle variants.
8. Create products with media, references, attributes, and vehicle fitments.
9. Create blog categories and tags.
10. Create blog articles and publish them after review.
11. Create API tokens and webhook endpoints for integrations.

## 5. Categories

Go to:

```text
Admin > Catalog > Categories
```

Categories organize products and provide SEO landing pages.

To create a category:

1. Open Categories.
2. Select Create.
3. Enter a name.
4. Optionally enter a slug. If left blank, the system generates one from the name.
5. Optionally select a parent category. Only top-level categories can be selected as parents.
6. Add a description.
7. Add SEO title, meta description, and meta keywords.
8. Set Active if the category should appear publicly and in active category selections.
9. Set Sort Order if needed.
10. Save.

Notes:

- Inactive categories are hidden from public-safe API slug reads and public category selections.
- Products can still exist in a category even if the category is inactive.
- Unknown system categories cannot be edited or deleted, only activated or deactivated.

## 6. Dynamic Attributes

Go to:

```text
Admin > Metadata > Attribute Groups
Admin > Metadata > Attributes
```

Attribute groups organize technical specs. Examples:

| Group | Example Attributes |
| --- | --- |
| Electrical | Voltage, Pin Count, Connector Type |
| Dimensions | Diameter, Thickness, Length |
| Fitment Details | Side, Position, Body Type Notes |

To create an attribute group:

1. Open Attribute Groups.
2. Select Create.
3. Enter name, optional slug, description, active state, and sort order.
4. Save.

To create an attribute:

1. Open Attributes.
2. Select Create.
3. Optionally select an attribute group.
4. Enter name and optional slug.
5. Select type: `text`, `number`, or `boolean`.
6. Enter a unit when useful, for example `V`, `mm`, `pins`, or `Nm`.
7. Mark Required only if every product must provide this value.
8. Set Active and Sort Order.
9. Save.

Notes:

- Required active attributes are enforced when saving products.
- Boolean attributes accept yes/no style values in the UI.
- Deactivating an attribute hides it from active product forms but does not remove existing stored values.

## 7. Vehicle Catalog

Vehicle fitment data is managed from:

```text
Admin > Vehicles
```

Current vehicle modules:

| Page | Purpose |
| --- | --- |
| Brands | Vehicle makes, for example BMW |
| Manufacturers | Engine and gearbox manufacturers, for example ZF or Bosch |
| Models | Vehicle model lines, for example 5 Series |
| Generations | Generation codes and year ranges, for example E34 |
| Engines | Engine codes and technical details, for example M51D25 |
| Gearboxes | Manual, automatic, dual-clutch, and CVT transmissions |
| Fuel Types | Diesel, Petrol, Hybrid, Electric |
| Body Styles | Sedan, Touring, Hatchback, Coupe |
| Drive Trains | FWD, RWD, AWD, 4WD |
| Vehicle Variants | Complete fitment records used by products |

### 7.1 Create Fuel Types, Body Styles, and Drive Trains

Create these first because engines, gearboxes, and vehicle variants depend on them.

For each page:

1. Open the page.
2. Select Create.
3. Enter name and optional slug.
4. Add description when needed.
5. Set Active.
6. Set Sort Order.
7. Save.

### 7.2 Create Vehicle Brands

Go to:

```text
Admin > Vehicles > Brands
```

To create a brand:

1. Select Create.
2. Enter name, for example `BMW`.
3. Optionally enter country, slug, description, active state, and sort order.
4. Save.

### 7.3 Create Vehicle Models

Go to:

```text
Admin > Vehicles > Models
```

To create a model:

1. Select Create.
2. Choose the vehicle brand.
3. Enter model name, for example `5 Series`.
4. Optionally enter slug, description, active state, and sort order.
5. Save.

Model names are unique per brand.

### 7.4 Create Manufacturers

Go to:

```text
Admin > Vehicles > Manufacturers
```

Manufacturers identify engine and gearbox producers. They are separate from vehicle brands because a BMW vehicle can use a ZF gearbox or Bosch component.

To create a manufacturer:

1. Select Create.
2. Enter name, for example `ZF`.
3. Optionally enter slug and country.
4. Save.

### 7.5 Create Vehicle Generations

Go to:

```text
Admin > Vehicles > Generations
```

To create a generation:

1. Select Create.
2. Choose the vehicle model.
3. Enter generation code, for example `E34`.
4. Optionally enter display name.
5. Optionally enter slug.
6. Enter year range when known.
7. Add notes.
8. Set Active and Sort Order.
9. Save.

Generation codes are unique per model.

### 7.6 Create Vehicle Engines

Go to:

```text
Admin > Vehicles > Engines
```

To create an engine:

1. Select Create.
2. Enter engine code, for example `M51D25`.
3. Optionally enter name and slug.
4. Optionally select manufacturer.
5. Select fuel type.
6. Enter technical data when known:
   - displacement in cc
   - displacement in liters
   - cylinders
   - valves
   - horsepower
   - horsepower range
   - torque in Nm
   - aspiration type
   - turbo or supercharged flags
   - engine layout
   - emission standard
   - production year range
7. Add notes.
8. Set Active and Sort Order.
9. Save.

### 7.7 Create Vehicle Gearboxes

Go to:

```text
Admin > Vehicles > Gearboxes
```

To create a gearbox:

1. Select Create.
2. Optionally select manufacturer.
3. Select gearbox type:
   - `Manual`
   - `Automatic`
   - `Dual Clutch`
   - `CVT`
4. Enter code and name when known.
5. Optionally select drive train.
6. Enter gear count, max torque, oil capacity, and production years when known.
7. Add notes.
8. Set Active and Sort Order.
9. Save.

### 7.8 Create Vehicle Variants

Go to:

```text
Admin > Vehicles > Vehicle Variants
```

A vehicle variant is the exact selectable fitment record used by products.

To create one:

1. Select Create.
2. Choose vehicle brand.
3. Choose model.
4. Choose generation.
5. Choose body style.
6. Choose drive train.
7. Choose engine. Fuel type is inherited from the selected engine.
8. Optionally choose one or more gearboxes.
9. Enter modification name, for example `525tds` or `320d`.
10. Enter `year_from` and `year_to`.
11. Optionally enter door count, market, and notes.
12. Set Active.
13. Set Sort Order.
14. Save.

Important:

- Active vehicle variants appear as selectable fitments on product forms.
- Product fitments can be marked `compatible` or `incompatible`.
- Use the Notes field for market limitations, trim limitations, installation cautions, or uncertainty.

## 8. Products

Go to:

```text
Admin > Catalog > Products
```

Products support:

- category
- name and slug
- SKU
- brand
- price
- draft or published status
- short and full descriptions
- SEO title, meta description, and meta keywords
- images and videos
- dynamic technical attributes
- vehicle fitments
- OEM, aftermarket, cross, and alternative references

To create a product:

1. Open Products.
2. Select Create.
3. Choose an active category if applicable.
4. Enter product name.
5. Optionally enter slug. If omitted, it is generated.
6. Enter SKU if available. SKU must be unique.
7. Enter brand.
8. Enter price in EUR. The system stores it internally as minor units.
9. Choose status:
   - `draft`: hidden from public product slug reads.
   - `published`: visible to public catalog reads.
10. Add short description and full description.
11. Fill SEO title, meta description, and meta keywords.
12. Upload product media.
13. Fill required and optional dynamic attributes.
14. Select vehicle fitments and choose `compatible` or `incompatible`.
15. Add references.
16. Save.

Product media rules:

- Supported media types: JPEG, PNG, WebP, GIF, MP4, WebM.
- Maximum upload size per file is 20 MB.
- Media is stored on the `public` disk under the product folder.
- On edit, existing media can be removed and new media can be uploaded.

Reference types:

| Type | Use |
| --- | --- |
| `oem` | Original equipment manufacturer numbers |
| `aftermarket` | Aftermarket manufacturer numbers |
| `cross` | Cross-reference numbers |
| `alternative` | Alternative replacement numbers |

Reference search is normalized. The system removes punctuation and casing differences for fast lookup, so values such as `13 62 7 520 519` and `13627520519` can match the same normalized number.

Fitment rules:

- Use `compatible` for verified matching vehicle records.
- Use `incompatible` when the product is known not to fit a vehicle that customers may confuse with a valid fitment.
- If compatibility is uncertain, do not mark it compatible. Add notes or leave it unassigned until verified.

Publishing rules:

- Published products are available through public catalog and slug API reads.
- Draft products are still manageable by admins and can be returned by API list endpoints only when `include_unpublished=1` is used with a token that has product read access.

## 9. Orders

Go to:

```text
Admin > Catalog > Orders
```

The admin order page supports searching, creating, viewing, editing, deleting, and updating fulfillment status.

Order statuses:

| Status | Meaning |
| --- | --- |
| `placed` | Order has been placed |
| `processing` | Order is being prepared |
| `completed` | Order is fulfilled |
| `cancelled` | Order was cancelled |

To create an order:

1. Open Orders.
2. Select Create Order.
3. Optionally select a saved customer to fill contact and address fields.
4. Enter or confirm customer name, email, phone, and shipping address.
5. Select status and currency. New admin orders default to `EUR`.
6. Optionally enter order number. If left blank, the system generates one.
7. Add one or more line items.
8. Select a catalog product to fill product name, slug, SKU, and price, or enter a manual external item.
9. Confirm quantity, unit price in minor units, and line total.
10. Optionally enter total in minor units. If left blank, the system uses the calculated subtotal.
11. Save.

To edit an order:

1. Open Orders.
2. Select Edit.
3. Update customer, address, status, notes, or line items.
4. Save.

To update an order status:

1. Open Orders.
2. Search or open the order.
3. Select the new status.
4. Save.

To delete an order:

1. Open Orders.
2. Select Delete.
3. Confirm deletion.

Order behavior:

- Checkout, API, and admin-created orders use the same order actions.
- Creating orders dispatches `order.created`.
- Full order edits and status-only updates dispatch `order.updated` when data changes.
- Product line items store product snapshots so historical orders remain readable after catalog edits.

## 10. Customers

Go to:

```text
Admin > Catalog > Customers
```

The customer admin page supports searching, creating, viewing, editing, deleting, and inspecting related orders.

To create a customer:

1. Open Customers.
2. Select Create Customer.
3. Enter name and email.
4. Optionally enter phone, address fields, and password.
5. Save.

To edit a customer:

1. Open Customers.
2. Select Edit.
3. Update profile, contact, or address fields.
4. Leave password blank to keep the existing password.
5. Save.

To delete a customer:

1. Open Customers.
2. Select Delete.
3. Confirm deletion.

Important:

- Customers with orders cannot be deleted.
- Customer creation and updates are available through admin and API. Customers may also be created through registration or checkout behavior.

## 11. Blog

Go to:

```text
Admin > Blog
```

The blog module supports SEO growth, product education, installation guides, diagnostics, and comparison content.

### 11.1 Blog Categories

Go to:

```text
Admin > Blog > Categories
```

To create a category:

1. Select Create.
2. Enter name, optional slug, description, active state, and sort order.
3. Save.

### 11.2 Blog Tags

Go to:

```text
Admin > Blog > Tags
```

To create a tag:

1. Select Create.
2. Enter name, optional slug, description, active state, and sort order.
3. Save.

### 11.3 Blog Articles

Go to:

```text
Admin > Blog > Articles
```

To create an article:

1. Select Create.
2. Choose blog category if applicable.
3. Choose author.
4. Enter title.
5. Optionally enter slug.
6. Enter excerpt.
7. Write the body.
8. Choose status:
   - `draft`
   - `published`
9. Choose content font:
   - `sans`
   - `serif`
   - `technical`
10. Enter SEO title and meta description.
11. Set publish date/time when publishing.
12. Select tags.
13. Upload article media if needed.
14. Save.

Publishing rules:

- A public article must have status `published`.
- A public article must have `published_at` set and not be in the future.
- Draft articles are not returned by public-safe slug reads.
- Publishing an article can dispatch `article.published`.

Article media rules:

- Supported media types: JPEG, PNG, WebP, GIF, MP4, WebM.
- Maximum upload size per file is 20 MB.

## 12. AI Content Suggestions

Go to:

```text
Admin > Blog > AI Content
```

AI suggestions can help with:

- blog drafts
- product descriptions
- SEO suggestions
- FAQ generation

Current request types:

| Type | Label |
| --- | --- |
| `blog_draft` | Blog draft |
| `product_description` | Product description |
| `seo_suggestions` | SEO suggestions |
| `faq` | FAQ generation |

Supported linked subjects:

| Subject | Use |
| --- | --- |
| `product` | Generate or apply content for a product |
| `blog_article` | Generate or apply content for a blog article |

AI suggestion statuses:

| Status | Meaning |
| --- | --- |
| `draft` | Needs review |
| `reviewed` | Human reviewed |
| `applied` | Applied to linked subject |
| `archived` | Archived and no longer active |

To generate a suggestion:

1. Open AI Content.
2. Select Create.
3. Choose request type.
4. Optionally choose subject type.
5. Select a saved product or article when linking to a subject.
6. Add custom context when needed.
7. Generate.
8. Review the generated suggestion.

To approve and apply a suggestion:

1. Open the suggestion.
2. Read the prompt, input snapshot, generated content, FAQs, keywords, and warnings.
3. Verify all technical claims, fitment statements, OEM references, and SEO text.
4. Mark the suggestion as Reviewed.
5. If the suggestion has applicable fields and is linked to a product or article, select Apply.

Apply behavior:

- Product description suggestions can update product short description, description, SEO title, meta description, and meta keywords.
- Product SEO suggestions can update SEO title, meta description, and meta keywords.
- Blog draft suggestions can update article title, excerpt, body, SEO title, and meta description.
- Blog SEO suggestions can update SEO title and meta description.
- Applying product suggestions dispatches `product.updated`.
- Applying AI content does not publish blog articles.

AI configuration:

The current implementation uses an Ollama-compatible chat completions endpoint. Environment variables:

```env
OLLAMA_BASE_URL=http://127.0.0.1:11434/v1
OLLAMA_MODEL=qwen3:1.7b
OLLAMA_API_KEY=ollama
OLLAMA_TIMEOUT=300
```

If AI generation fails, confirm the Ollama server is running, the model is installed, and the configured endpoint supports `/chat/completions`.

## 13. API Tokens

Go to:

```text
Admin > Webhooks & APIs > API Tokens
```

API tokens are Sanctum bearer tokens used by developers and integrations.

To create a token:

1. Open API Tokens.
2. Select Create.
3. Enter token name.
4. Select abilities.
5. Set Active.
6. Optionally set expiration date/time.
7. Save.
8. Copy the plaintext token immediately.

Important:

- The plaintext API token is shown only once after creation.
- Inactive or expired tokens cannot access the API.
- Use the smallest set of abilities required for the integration.
- `*` grants full API access.

Ability groups:

| Group | Abilities |
| --- | --- |
| Products | `products.read`, `products.create`, `products.update`, `products.delete` |
| Categories | `categories.read`, `categories.create`, `categories.update`, `categories.delete` |
| Attributes | `attributes.read`, `attributes.create`, `attributes.update`, `attributes.delete` |
| Vehicles | `vehicles.read`, `vehicles.create`, `vehicles.update`, `vehicles.delete` |
| Blog | `blog.read`, `blog.create`, `blog.update`, `blog.delete` |
| Customers | `customers.read`, `customers.create`, `customers.update`, `customers.delete` |
| Orders | `orders.lookup`, `orders.read`, `orders.create`, `orders.update`, `orders.delete` |
| Webhooks | `webhooks.read`, `webhooks.create`, `webhooks.update`, `webhooks.delete`, `webhooks.retry` |

## 14. Webhooks

Go to:

```text
Admin > Webhooks & APIs > Webhook Endpoints
Admin > Webhooks & APIs > Webhook Logs
```

Supported events:

| Event | Meaning |
| --- | --- |
| `product.created` | Product created |
| `product.updated` | Product updated |
| `product.deleted` | Product deleted |
| `order.created` | Order created |
| `order.updated` | Order updated |
| `article.published` | Article published |

To create a webhook endpoint:

1. Open Webhook Endpoints.
2. Select Create.
3. Enter name.
4. Enter receiver URL.
5. Optionally enter a secret with at least 16 characters. If omitted, the system generates one.
6. Select subscribed events.
7. Optionally enter headers as JSON.
8. Set Active.
9. Set Max Attempts from 1 to 10.
10. Set Timeout Seconds from 1 to 30.
11. Save.

To inspect delivery logs:

1. Open Webhook Logs.
2. Search or filter delivery records.
3. Open a delivery to inspect payload, status, attempts, response, and error message.
4. Retry failed deliveries when appropriate.

Webhook delivery requires a running queue worker:

```bash
php artisan queue:work
```

Receivers should verify the HMAC signature in `X-Parts-Webhook-Signature`.

## 15. Public Storefront Checks

Use the Storefront link or visit:

```text
/
/catalog
/products/{product-slug}
/blog
/blog/{article-slug}
/cart
/login
/register
/checkout
/account/orders
```

After publishing products or articles, verify:

- product pages load
- images and videos display
- SEO title and meta description are correct
- references and compatibility are accurate
- article publish date is not in the future
- draft content is not visible publicly

Checkout and account behavior:

- Adding items to the cart accepts only published products.
- Cart display, summaries, and checkout remove unpublished or missing products from the active cart.
- Checkout requires a signed-in user and redirects empty carts back to `/cart`.
- Checkout stores customer contact, shipping address, order notes, and product snapshots on the order.
- Customers can view their own orders under `/account/orders`.
- Admin users can view account order detail pages when needed for support.

## 16. Plugin Operations

Plugins are file-based extensions loaded from:

```text
plugins/
```

The default plugin path can be changed with:

```env
PARTS_PLUGINS_PATH=/absolute/path/to/plugins
```

By default, all plugins with `"enabled": true` in `plugin.json` are loaded. To allow only specific manifest names, set:

```env
PARTS_ENABLED_PLUGINS=Vendor/InventorySync,Vendor/AnotherPlugin
```

To scaffold a plugin:

```bash
php artisan parts:make-plugin Vendor/InventorySync
```

The scaffold creates:

```text
plugin.json
src/PluginServiceProvider.php
routes/api.php
routes/web.php
database/migrations/
README.md
```

Plugin route defaults:

| Route Type | Default Prefix |
| --- | --- |
| Web | `/plugins/{plugin-slug}` |
| API | `/api/v1/plugins/{plugin-slug}` |

Operational notes:

- Set `"enabled": false` in `plugin.json` to disable a plugin without deleting files.
- Plugin service providers are registered when the provider class exists.
- Plugin migrations are loaded when the configured migrations directory exists.
- Plugin routes should define their own authentication, authorization, throttling, and validation rules when they expose sensitive behavior.
- Developer-facing plugin instructions are in [Plugin Development Guide](PLUGIN_DEVELOPMENT.md).

## 17. Operational Checklist

Before considering admin-entered content complete:

1. Product name, SKU, brand, price, and status are correct.
2. Product references are entered and normalized duplicates are avoided.
3. Vehicle compatibility is verified and not guessed.
4. Technical attributes are complete.
5. Product media is relevant and has meaningful alt text where supported.
6. SEO title and meta description are reviewed.
7. AI-generated content has been reviewed by a human.
8. Blog articles have category, tags, publish date, and metadata.
9. API tokens use least-privilege abilities.
10. Webhook endpoints are active, subscribed to the correct events, and tested.
11. Checkout, account order pages, API tokens, and webhooks have been smoke-tested after related configuration changes.

Before considering repository work complete, run:

```bash
composer lint:check
php artisan test
npm run format:check
npm run lint:check
npm run types:check
npm run build
```

## 18. Troubleshooting

If you cannot access `/admin`:

- Confirm you are using `/admin/login`.
- Confirm the account has the `admin` role.
- Use `php artisan parts:make-admin` to create or promote an admin account.

If products do not appear publicly:

- Confirm product status is `published`.
- Confirm category is active.
- Confirm the slug is correct.
- Confirm media files exist on the public disk.

If a required attribute blocks saving:

- Open Metadata > Attributes.
- Check which active attributes are marked Required.
- Either fill the required value on the product or change the attribute requirement if it should not apply globally.

If a vehicle variant does not appear in product fitment options:

- Confirm the vehicle variant is Active.
- Confirm its make, model, generation, body style, drive train, engine, and optional gearbox records exist.

If AI generation fails:

- Confirm `OLLAMA_MODEL` is configured.
- Confirm the Ollama server is running.
- Confirm the model is installed.
- Check application logs for the exact error.

If webhooks do not send:

- Confirm the endpoint is Active.
- Confirm it subscribes to the event.
- Confirm the queue worker is running.
- Check Webhook Logs for response status or error message.

If a plugin does not load:

- Confirm `plugin.json` exists and contains a non-empty `name`.
- Confirm `"enabled": true` in the plugin manifest.
- Confirm `PARTS_ENABLED_PLUGINS` is either `*` or includes the exact manifest name.
- Confirm the provider file path and provider class match the manifest.
- Run `php artisan route:list` to confirm plugin routes are registered.
