type: compacted

type: message

role: developer

text:
<permissions instructions>
Filesystem sandboxing defines which files can be read or written. `sandbox_mode` is `danger-full-access`: No filesystem sandboxing - all commands are permitted. Network access is enabled.
Approval policy is currently never. Do not provide the `sandbox_permissions` for any reason, commands will be rejected.
</permissions instructions>

text:
<skills_instructions>
## Skills
A skill is a set of local instructions to follow that is stored in a `SKILL.md` file. Below is the list of skills that can be used. Each entry includes a name, description, and file path so you can open the source for full instructions when using a specific skill.
### Available skills
- imagegen: Generate or edit raster images when the task benefits from AI-created bitmap visuals such as photos, illustrations, textures, sprites, mockups, or transparent-background cutouts. Use when Codex should create a brand-new image, transform an existing image, or derive visual variants from references, and the output should be a bitmap asset rather than repo-native code or vector. Do not use when the task is better handled by editing existing SVG/vector/code-native assets, extending an established icon or logo system, or building the visual directly in HTML/CSS/canvas. (file: /Users/fabianwesner/.codex/skills/.system/imagegen/SKILL.md)
- openai-docs: Use when the user asks how to build with OpenAI products or APIs and needs up-to-date official documentation with citations, help choosing the latest model for a use case, or model upgrade and prompt-upgrade guidance; prioritize OpenAI docs MCP tools, use bundled references only as helper context, and restrict any fallback browsing to official OpenAI domains. (file: /Users/fabianwesner/.codex/skills/.system/openai-docs/SKILL.md)
- plugin-creator: Create and scaffold plugin directories for Codex with a required `.codex-plugin/plugin.json`, optional plugin folders/files, and baseline placeholders you can edit before publishing or testing. Use when Codex needs to create a new local plugin, add optional plugin structure, or generate or update repo-root `.agents/plugins/marketplace.json` entries for plugin ordering and availability metadata. (file: /Users/fabianwesner/.codex/skills/.system/plugin-creator/SKILL.md)
- skill-creator: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Codex's capabilities with specialized knowledge, workflows, or tool integrations. (file: /Users/fabianwesner/.codex/skills/.system/skill-creator/SKILL.md)
- skill-installer: Install Codex skills into $CODEX_HOME/skills from a curated list or a GitHub repo path. Use when a user asks to list installable skills, install a curated skill, or install a skill from another repo (including private repos). (file: /Users/fabianwesner/.codex/skills/.system/skill-installer/SKILL.md)
- developing-with-fortify: Laravel Fortify headless authentication backend development. Activate when implementing authentication features including login, registration, password reset, email verification, two-factor authentication (2FA/TOTP), profile updates, headless auth, authentication scaffolding, or auth guards in Laravel applications. (file: /Users/fabianwesner/Herd/shop/.agents/skills/developing-with-fortify/SKILL.md)
- fluxui-development: Use this skill for Flux UI development in Livewire applications only. Trigger when working with <flux:*> components, building or customizing Livewire component UIs, creating forms, modals, tables, or other interactive elements. Covers: flux: components (buttons, inputs, modals, forms, tables, date-pickers, kanban, badges, tooltips, etc.), component composition, Tailwind CSS styling, Heroicons/Lucide icon integration, validation patterns, responsive design, and theming. Do not use for non-Livewire frameworks or non-component styling. (file: /Users/fabianwesner/Herd/shop/.agents/skills/fluxui-development/SKILL.md)
- laravel-best-practices: Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code. This includes creating or modifying controllers, models, migrations, form requests, policies, jobs, scheduled commands, service classes, and Eloquent queries. Triggers for N+1 and query performance issues, caching strategies, authorization and security patterns, validation, error handling, queue and job configuration, route definitions, and architectural decisions. Also use for Laravel code reviews and refactoring existing Laravel code to follow best practices. Covers any task involving Laravel backend PHP code patterns. (file: /Users/fabianwesner/Herd/shop/.agents/skills/laravel-best-practices/SKILL.md)
- livewire-development: Use for any task or question involving Livewire. Activate if user mentions Livewire, wire: directives, or Livewire-specific concepts like wire:model, wire:click, wire:sort, or islands, invoke this skill. Covers building new components, debugging reactivity issues, real-time form validation, drag-and-drop, loading states, migrating from Livewire 3 to 4, converting component formats (SFC/MFC/class-based), and performance optimization. Do not use for non-Livewire reactive UI (React, Vue, Alpine-only, Inertia.js) or standard Laravel forms without Livewire. (file: /Users/fabianwesner/Herd/shop/.agents/skills/livewire-development/SKILL.md)
- pest-testing: Use this skill for Pest PHP testing in Laravel projects only. Trigger whenever any test is being written, edited, fixed, or refactored — including fixing tests that broke after a code change, adding assertions, converting PHPUnit to Pest, adding datasets, and TDD workflows. Always activate when the user asks how to write something in Pest, mentions test files or directories (tests/Feature, tests/Unit, tests/Browser), or needs browser testing, smoke testing multiple pages for JS errors, or architecture tests. Covers: test()/it()/expect() syntax, datasets, mocking, browser testing (visit/click/fill), smoke testing, arch(), Livewire component tests, RefreshDatabase, and all Pest 4 features. Do not use for factories, seeders, migrations, controllers, models, or non-test PHP code. (file: /Users/fabianwesner/Herd/shop/.agents/skills/pest-testing/SKILL.md)
- tailwindcss-development: Always invoke when the user's message includes 'tailwind' in any form. Also invoke for: building responsive grid layouts (multi-column card grids, product grids), flex/grid page structures (dashboards with sidebars, fixed topbars, mobile-toggle navs), styling UI components (cards, tables, navbars, pricing sections, forms, inputs, badges), adding dark mode variants, fixing spacing or typography, and Tailwind v3/v4 work. The core use case: writing or fixing Tailwind utility classes in HTML templates (Blade, JSX, Vue). Skip for backend PHP logic, database queries, API routes, JavaScript with no HTML/CSS component, CSS file audits, build tool configuration, and vanilla CSS. (file: /Users/fabianwesner/Herd/shop/.agents/skills/tailwindcss-development/SKILL.md)
### How to use skills
- Discovery: The list above is the skills available in this session (name + description + file path). Skill bodies live on disk at the listed paths.
- Trigger rules: If the user names a skill (with `$SkillName` or plain text) OR the task clearly matches a skill's description shown above, you must use that skill for that turn. Multiple mentions mean use them all. Do not carry skills across turns unless re-mentioned.
- Missing/blocked: If a named skill isn't in the list or the path can't be read, say so briefly and continue with the best fallback.
- How to use a skill (progressive disclosure):
  1) After deciding to use a skill, open its `SKILL.md`. Read only enough to follow the workflow.
  2) When `SKILL.md` references relative paths (e.g., `scripts/foo.py`), resolve them relative to the skill directory listed above first, and only consider other paths if needed.
  3) If `SKILL.md` points to extra folders such as `references/`, load only the specific files needed for the request; don't bulk-load everything.
  4) If `scripts/` exist, prefer running or patching them instead of retyping large code blocks.
  5) If `assets/` or templates exist, reuse them instead of recreating from scratch.
- Coordination and sequencing:
  - If multiple skills apply, choose the minimal set that covers the request and state the order you'll use them.
  - Announce which skill(s) you're using and why (one short line). If you skip an obvious skill, say why.
- Context hygiene:
  - Keep context small: summarize long sections instead of pasting them; only load extra files when needed.
  - Avoid deep reference-chasing: prefer opening only files directly linked from `SKILL.md` unless you're blocked.
  - When variants exist (frameworks, providers, domains), pick only the relevant reference file(s) and note that choice.
- Safety and fallback: If a skill can't be applied cleanly (missing files, unclear instructions), state the issue, pick the next-best approach, and continue.
</skills_instructions>

role: user

text:
# AGENTS.md instructions for /Users/fabianwesner/Herd/shop

<INSTRUCTIONS>
# Shop

Self-contained e-commerce platform with multi-tenant support, product catalog, cart, checkout, payments (mock PSP), order management, customer accounts, and an admin panel.

## Tech Stack

- PHP 8.4 / Laravel 12
- Livewire v4 / Flux UI Free v2
- Tailwind CSS v4
- SQLite
- Pest v4

## Specs

The complete specification is in `specs/`. Start with `specs/09-IMPLEMENTATION-ROADMAP.md` for the build order, then reference the other files as needed:

- `specs/01-DATABASE-SCHEMA.md` - Database schema
- `specs/02-API-ROUTES.md` - Routes and API endpoints
- `specs/03-ADMIN-UI.md` - Admin panel
- `specs/04-STOREFRONT-UI.md` - Storefront
- `specs/05-BUSINESS-LOGIC.md` - Business logic
- `specs/06-AUTH-AND-SECURITY.md` - Auth and security
- `specs/07-SEEDERS-AND-TEST-DATA.md` - Seeders and test data
- `specs/08-PLAYWRIGHT-E2E-PLAN.md` - E2E browser tests
- `specs/09-IMPLEMENTATION-ROADMAP.md` - Implementation roadmap

===

<laravel-boost-guidelines>
=== 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.4
- laravel/fortify (FORTIFY) - v1
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- livewire/flux (FLUXUI_FREE) - v2
- livewire/livewire (LIVEWIRE) - v4
- laravel/boost (BOOST) - v2
- laravel/mcp (MCP) - v0
- laravel/pail (PAIL) - v1
- laravel/pint (PINT) - v1
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v4
- phpunit/phpunit (PHPUNIT) - v12
- tailwindcss (TAILWINDCSS) - v4

## Skills Activation

This project has domain-specific skills available. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.

- `developing-with-fortify` — Laravel Fortify headless authentication backend development. Activate when implementing authentication features including login, registration, password reset, email verification, two-factor authentication (2FA/TOTP), profile updates, headless auth, authentication scaffolding, or auth guards in Laravel applications.
- `laravel-best-practices` — Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code. This includes creating or modifying controllers, models, migrations, form requests, policies, jobs, scheduled commands, service classes, and Eloquent queries. Triggers for N+1 and query performance issues, caching strategies, authorization and security patterns, validation, error handling, queue and job configuration, route definitions, and architectural decisions. Also use for Laravel code reviews and refactoring existing Laravel code to follow best practices. Covers any task involving Laravel backend PHP code patterns.
- `fluxui-development` — Use this skill for Flux UI development in Livewire applications only. Trigger when working with <flux:*> components, building or customizing Livewire component UIs, creating forms, modals, tables, or other interactive elements. Covers: flux: components (buttons, inputs, modals, forms, tables, date-pickers, kanban, badges, tooltips, etc.), component composition, Tailwind CSS styling, Heroicons/Lucide icon integration, validation patterns, responsive design, and theming. Do not use for non-Livewire frameworks or non-component styling.
- `livewire-development` — Use for any task or question involving Livewire. Activate if user mentions Livewire, wire: directives, or Livewire-specific concepts like wire:model, wire:click, wire:sort, or islands, invoke this skill. Covers building new components, debugging reactivity issues, real-time form validation, drag-and-drop, loading states, migrating from Livewire 3 to 4, converting component formats (SFC/MFC/class-based), and performance optimization. Do not use for non-Livewire reactive UI (React, Vue, Alpine-only, Inertia.js) or standard Laravel forms without Livewire.
- `pest-testing` — Use this skill for Pest PHP testing in Laravel projects only. Trigger whenever any test is being written, edited, fixed, or refactored — including fixing tests that broke after a code change, adding assertions, converting PHPUnit to Pest, adding datasets, and TDD workflows. Always activate when the user asks how to write something in Pest, mentions test files or directories (tests/Feature, tests/Unit, tests/Browser), or needs browser testing, smoke testing multiple pages for JS errors, or architecture tests. Covers: test()/it()/expect() syntax, datasets, mocking, browser testing (visit/click/fill), smoke testing, arch(), Livewire component tests, RefreshDatabase, and all Pest 4 features. Do not use for factories, seeders, migrations, controllers, models, or non-test PHP code.
- `tailwindcss-development` — Always invoke when the user's message includes 'tailwind' in any form. Also invoke for: building responsive grid layouts (multi-column card grids, product grids), flex/grid page structures (dashboards with sidebars, fixed topbars, mobile-toggle navs), styling UI components (cards, tables, navbars, pricing sections, forms, inputs, badges), adding dark mode variants, fixing spacing or typography, and Tailwind v3/v4 work. The core use case: writing or fixing Tailwind utility classes in HTML templates (Blade, JSX, Vue). Skip for backend PHP logic, database queries, API routes, JavaScript with no HTML/CSS component, CSS file audits, build tool configuration, and vanilla CSS.

## 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 `npm run build`, `npm 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.
- To check environment variables, read the `.env` file directly.

## 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.

=== herd rules ===

# Laravel Herd

- The application is served by Laravel Herd at `https?://[kebab-case-project-dir].test`. Use the `get-absolute-url` tool to generate valid URLs. Never run commands to serve the site. It is always available.
- Use the `herd` CLI to manage services, PHP versions, and sites (e.g. `herd sites`, `herd services:start <service>`, `herd php:list`). Run `herd list` to discover all available commands.

=== tests rules ===

# Test Enforcement

- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test --compact` with a specific filename or filter.

=== fortify/core rules ===

# Laravel Fortify

- Fortify is a headless authentication backend that provides authentication routes and controllers for Laravel applications.
- IMPORTANT: Always use the `search-docs` tool for detailed Laravel Fortify patterns and documentation.
- IMPORTANT: Activate `developing-with-fortify` skill when working with Fortify authentication features.

=== 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 `npm run build` or ask the user to run `npm run dev` or `composer run dev`.

=== laravel/v12 rules ===

# Laravel 12

- CRITICAL: ALWAYS use `search-docs` tool for version-specific Laravel documentation and updated code examples.
- Since Laravel 11, Laravel has a new streamlined file structure which this project uses.

## Laravel 12 Structure

- In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`.
- Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`.
- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files.
- `bootstrap/providers.php` contains application specific service providers.
- The `app/Console/Kernel.php` file no longer exists; use `bootstrap/app.php` or `routes/console.php` for console configuration.
- Console commands in `app/Console/Commands/` are automatically available and do not require manual registration.

## Database

- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost.
- Laravel 12 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.

### Models

- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models.

=== livewire/core rules ===

# Livewire

- Livewire allow to build dynamic, reactive interfaces in PHP without writing JavaScript.
- You can use Alpine.js for client-side interactions instead of JavaScript frameworks.
- Keep state server-side so the UI reflects it. Validate and authorize in actions as you would in HTTP requests.

=== pint/core rules ===

# Laravel Pint Code Formatter

- If you have modified any PHP files, you must run `vendor/bin/pint --dirty --format agent` before finalizing changes to ensure your code matches the project's expected style.
- Do not run `vendor/bin/pint --test --format agent`, simply run `vendor/bin/pint --format agent` to fix any formatting issues.

=== pest/core rules ===

## Pest

- This project uses Pest for testing. Create tests: `php artisan make:test --pest {name}`.
- Run tests: `php artisan test --compact` or filter: `php artisan test --compact --filter=testName`.
- Do NOT delete tests without approval.

</laravel-boost-guidelines>

</INSTRUCTIONS>

text:
<environment_context>
  <cwd>/Users/fabianwesner/Herd/shop</cwd>
  <shell>zsh</shell>
  <current_date>2026-05-03</current_date>
  <timezone>Europe/Berlin</timezone>
  <subagents>
    - 019df0be-48af-7a51-8af7-26927c73f182: Mill
    - 019df0be-4901-7860-b0a7-7b1ba065d58c: Ohm
  </subagents>
</environment_context>

type: compaction


timezone: Europe/Berlin

approval_policy: never

type: danger-full-access

type: disabled

personality: pragmatic

mode: default

reasoning_effort: xhigh

effort: xhigh

user_instructions:
# Shop

Self-contained e-commerce platform with multi-tenant support, product catalog, cart, checkout, payments (mock PSP), order management, customer accounts, and an admin panel.

## Tech Stack

- PHP 8.4 / Laravel 12
- Livewire v4 / Flux UI Free v2
- Tailwind CSS v4
- SQLite
- Pest v4

## Specs

The complete specification is in `specs/`. Start with `specs/09-IMPLEMENTATION-ROADMAP.md` for the build order, then reference the other files as needed:

- `specs/01-DATABASE-SCHEMA.md` - Database schema
- `specs/02-API-ROUTES.md` - Routes and API endpoints
- `specs/03-ADMIN-UI.md` - Admin panel
- `specs/04-STOREFRONT-UI.md` - Storefront
- `specs/05-BUSINESS-LOGIC.md` - Business logic
- `specs/06-AUTH-AND-SECURITY.md` - Auth and security
- `specs/07-SEEDERS-AND-TEST-DATA.md` - Seeders and test data
- `specs/08-PLAYWRIGHT-E2E-PLAN.md` - E2E browser tests
- `specs/09-IMPLEMENTATION-ROADMAP.md` - Implementation roadmap

===

<laravel-boost-guidelines>
=== 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.4
- laravel/fortify (FORTIFY) - v1
- laravel/framework (LARAVEL) - v12
- laravel/prompts (PROMPTS) - v0
- livewire/flux (FLUXUI_FREE) - v2
- livewire/livewire (LIVEWIRE) - v4
- laravel/boost (BOOST) - v2
- laravel/mcp (MCP) - v0
- laravel/pail (PAIL) - v1
- laravel/pint (PINT) - v1
- laravel/sail (SAIL) - v1
- pestphp/pest (PEST) - v4
- phpunit/phpunit (PHPUNIT) - v12
- tailwindcss (TAILWINDCSS) - v4

## Skills Activation

This project has domain-specific skills available. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.

- `developing-with-fortify` — Laravel Fortify headless authentication backend development. Activate when implementing authentication features including login, registration, password reset, email verification, two-factor authentication (2FA/TOTP), profile updates, headless auth, authentication scaffolding, or auth guards in Laravel applications.
- `laravel-best-practices` — Apply this skill whenever writing, reviewing, or refactoring Laravel PHP code. This includes creating or modifying controllers, models, migrations, form requests, policies, jobs, scheduled commands, service classes, and Eloquent queries. Triggers for N+1 and query performance issues, caching strategies, authorization and security patterns, validation, error handling, queue and job configuration, route definitions, and architectural decisions. Also use for Laravel code reviews and refactoring existing Laravel code to follow best practices. Covers any task involving Laravel backend PHP code patterns.
- `fluxui-development` — Use this skill for Flux UI development in Livewire applications only. Trigger when working with <flux:*> components, building or customizing Livewire component UIs, creating forms, modals, tables, or other interactive elements. Covers: flux: components (buttons, inputs, modals, forms, tables, date-pickers, kanban, badges, tooltips, etc.), component composition, Tailwind CSS styling, Heroicons/Lucide icon integration, validation patterns, responsive design, and theming. Do not use for non-Livewire frameworks or non-component styling.
- `livewire-development` — Use for any task or question involving Livewire. Activate if user mentions Livewire, wire: directives, or Livewire-specific concepts like wire:model, wire:click, wire:sort, or islands, invoke this skill. Covers building new components, debugging reactivity issues, real-time form validation, drag-and-drop, loading states, migrating from Livewire 3 to 4, converting component formats (SFC/MFC/class-based), and performance optimization. Do not use for non-Livewire reactive UI (React, Vue, Alpine-only, Inertia.js) or standard Laravel forms without Livewire.
- `pest-testing` — Use this skill for Pest PHP testing in Laravel projects only. Trigger whenever any test is being written, edited, fixed, or refactored — including fixing tests that broke after a code change, adding assertions, converting PHPUnit to Pest, adding datasets, and TDD workflows. Always activate when the user asks how to write something in Pest, mentions test files or directories (tests/Feature, tests/Unit, tests/Browser), or needs browser testing, smoke testing multiple pages for JS errors, or architecture tests. Covers: test()/it()/expect() syntax, datasets, mocking, browser testing (visit/click/fill), smoke testing, arch(), Livewire component tests, RefreshDatabase, and all Pest 4 features. Do not use for factories, seeders, migrations, controllers, models, or non-test PHP code.
- `tailwindcss-development` — Always invoke when the user's message includes 'tailwind' in any form. Also invoke for: building responsive grid layouts (multi-column card grids, product grids), flex/grid page structures (dashboards with sidebars, fixed topbars, mobile-toggle navs), styling UI components (cards, tables, navbars, pricing sections, forms, inputs, badges), adding dark mode variants, fixing spacing or typography, and Tailwind v3/v4 work. The core use case: writing or fixing Tailwind utility classes in HTML templates (Blade, JSX, Vue). Skip for backend PHP logic, database queries, API routes, JavaScript with no HTML/CSS component, CSS file audits, build tool configuration, and vanilla CSS.

## 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 `npm run build`, `npm 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.
- To check environment variables, read the `.env` file directly.

## 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.

=== herd rules ===

# Laravel Herd

- The application is served by Laravel Herd at `https?://[kebab-case-project-dir].test`. Use the `get-absolute-url` tool to generate valid URLs. Never run commands to serve the site. It is always available.
- Use the `herd` CLI to manage services, PHP versions, and sites (e.g. `herd sites`, `herd services:start <service>`, `herd php:list`). Run `herd list` to discover all available commands.

=== tests rules ===

# Test Enforcement

- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test --compact` with a specific filename or filter.

=== fortify/core rules ===

# Laravel Fortify

- Fortify is a headless authentication backend that provides authentication routes and controllers for Laravel applications.
- IMPORTANT: Always use the `search-docs` tool for detailed Laravel Fortify patterns and documentation.
- IMPORTANT: Activate `developing-with-fortify` skill when working with Fortify authentication features.

=== 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 `npm run build` or ask the user to run `npm run dev` or `composer run dev`.

=== laravel/v12 rules ===

# Laravel 12

- CRITICAL: ALWAYS use `search-docs` tool for version-specific Laravel documentation and updated code examples.
- Since Laravel 11, Laravel has a new streamlined file structure which this project uses.

## Laravel 12 Structure

- In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`.
- Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`.
- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files.
- `bootstrap/providers.php` contains application specific service providers.
- The `app/Console/Kernel.php` file no longer exists; use `bootstrap/app.php` or `routes/console.php` for console configuration.
- Console commands in `app/Console/Commands/` are automatically available and do not require manual registration.

## Database

- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost.
- Laravel 12 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`.

### Models

- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models.

=== livewire/core rules ===

# Livewire

- Livewire allow to build dynamic, reactive interfaces in PHP without writing JavaScript.
- You can use Alpine.js for client-side interactions instead of JavaScript frameworks.
- Keep state server-side so the UI reflects it. Validate and authorize in actions as you would in HTTP requests.

=== pint/core rules ===

# Laravel Pint Code Formatter

- If you have modified any PHP files, you must run `vendor/bin/pint --dirty --format agent` before finalizing changes to ensure your code matches the project's expected style.
- Do not run `vendor/bin/pint --test --format agent`, simply run `vendor/bin/pint --format agent` to fix any formatting issues.

=== pest/core rules ===

## Pest

- This project uses Pest for testing. Create tests: `php artisan make:test --pest {name}`.
- Run tests: `php artisan test --compact` or filter: `php artisan test --compact --filter=testName`.
- Do NOT delete tests without approval.

</laravel-boost-guidelines>

mode: tokens


message: I’ve finished the Phase 6 content/settings/theme/navigation implementation and verification. I’m cleaning the generated browser artifacts now, then I’ll commit this slice and move on to the next roadmap items.

phase: commentary


role: assistant

text: I’ve finished the Phase 6 content/settings/theme/navigation implementation and verification. I’m cleaning the generated browser artifacts now, then I’ll commit this slice and move on to the next roadmap items.


cmd: git ls-files --others --exclude-standard .playwright-mcp


command: git ls-files --others --exclude-standard .playwright-mcp

path: .playwright-mcp

status: completed


output:
Chunk ID: 008745
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 307
Output:
.playwright-mcp/console-2026-05-03T23-28-42-443Z.log
.playwright-mcp/console-2026-05-04T02-28-17-516Z.log
.playwright-mcp/console-2026-05-04T02-55-31-578Z.log
.playwright-mcp/console-2026-05-04T02-56-16-287Z.log
.playwright-mcp/console-2026-05-04T02-57-03-190Z.log
.playwright-mcp/console-2026-05-04T02-57-12-922Z.log
.playwright-mcp/console-2026-05-04T02-57-22-844Z.log
.playwright-mcp/console-2026-05-04T02-57-32-309Z.log
.playwright-mcp/console-2026-05-04T02-59-04-407Z.log
.playwright-mcp/page-2026-05-04T02-55-31-783Z.yml
.playwright-mcp/page-2026-05-04T02-55-43-522Z.yml
.playwright-mcp/page-2026-05-04T02-55-58-899Z.yml
.playwright-mcp/page-2026-05-04T02-56-05-373Z.yml
.playwright-mcp/page-2026-05-04T02-56-16-490Z.yml
.playwright-mcp/page-2026-05-04T02-56-37-496Z.yml
.playwright-mcp/page-2026-05-04T02-56-41-845Z.yml
.playwright-mcp/page-2026-05-04T02-56-53-392Z.yml
.playwright-mcp/page-2026-05-04T02-56-58-188Z.yml
.playwright-mcp/page-2026-05-04T02-57-03-425Z.yml
.playwright-mcp/page-2026-05-04T02-57-13-094Z.yml
.playwright-mcp/page-2026-05-04T02-57-23-037Z.yml
.playwright-mcp/page-2026-05-04T02-57-32-461Z.yml
.playwright-mcp/page-2026-05-04T02-57-44-228Z.yml
.playwright-mcp/page-2026-05-04T02-59-04-593Z.yml


command:
/bin/zsh
-lc
git diff --stat

type: unknown

cmd: git diff --stat

aggregated_output:
 resources/views/layouts/app/sidebar.blade.php | 20 ++++++++++++++++
 routes/web.php                                | 17 ++++++++++++++
 specs/progress.md                             | 33 ++++++++++++++++++++-------
 3 files changed, 62 insertions(+), 8 deletions(-)


command:
/bin/zsh
-lc
git status --short

cmd: git status --short

aggregated_output:
 M resources/views/layouts/app/sidebar.blade.php
 M routes/web.php
 M specs/progress.md
?? .playwright-mcp/console-2026-05-03T23-28-42-443Z.log
?? .playwright-mcp/console-2026-05-04T02-28-17-516Z.log
?? .playwright-mcp/console-2026-05-04T02-55-31-578Z.log
?? .playwright-mcp/console-2026-05-04T02-56-16-287Z.log
?? .playwright-mcp/console-2026-05-04T02-57-03-190Z.log
?? .playwright-mcp/console-2026-05-04T02-57-12-922Z.log
?? .playwright-mcp/console-2026-05-04T02-57-22-844Z.log
?? .playwright-mcp/console-2026-05-04T02-57-32-309Z.log
?? .playwright-mcp/console-2026-05-04T02-59-04-407Z.log
?? .playwright-mcp/page-2026-05-04T02-55-31-783Z.yml
?? .playwright-mcp/page-2026-05-04T02-55-43-522Z.yml
?? .playwright-mcp/page-2026-05-04T02-55-58-899Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-05-373Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-16-490Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-37-496Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-41-845Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-53-392Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-58-188Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-03-425Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-13-094Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-23-037Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-32-461Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-44-228Z.yml
?? .playwright-mcp/page-2026-05-04T02-59-04-593Z.yml
?? app/Livewire/Admin/Navigation/
?? app/Livewire/Admin/Pages/
?? app/Livewire/Admin/Settings/
?? app/Livewire/Admin/Themes/
?? resources/views/livewire/admin/navigation/
?? resources/views/livewire/admin/pages/
?? resources/views/livewire/admin/settings/
?? resources/views/livewire/admin/themes/
?? tests/Feature/Admin/ContentManagementTest.php
?? tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: 429c63
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 446
Output:
 M resources/views/layouts/app/sidebar.blade.php
 M routes/web.php
 M specs/progress.md
?? .playwright-mcp/console-2026-05-03T23-28-42-443Z.log
?? .playwright-mcp/console-2026-05-04T02-28-17-516Z.log
?? .playwright-mcp/console-2026-05-04T02-55-31-578Z.log
?? .playwright-mcp/console-2026-05-04T02-56-16-287Z.log
?? .playwright-mcp/console-2026-05-04T02-57-03-190Z.log
?? .playwright-mcp/console-2026-05-04T02-57-12-922Z.log
?? .playwright-mcp/console-2026-05-04T02-57-22-844Z.log
?? .playwright-mcp/console-2026-05-04T02-57-32-309Z.log
?? .playwright-mcp/console-2026-05-04T02-59-04-407Z.log
?? .playwright-mcp/page-2026-05-04T02-55-31-783Z.yml
?? .playwright-mcp/page-2026-05-04T02-55-43-522Z.yml
?? .playwright-mcp/page-2026-05-04T02-55-58-899Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-05-373Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-16-490Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-37-496Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-41-845Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-53-392Z.yml
?? .playwright-mcp/page-2026-05-04T02-56-58-188Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-03-425Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-13-094Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-23-037Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-32-461Z.yml
?? .playwright-mcp/page-2026-05-04T02-57-44-228Z.yml
?? .playwright-mcp/page-2026-05-04T02-59-04-593Z.yml
?? app/Livewire/Admin/Navigation/
?? app/Livewire/Admin/Pages/
?? app/Livewire/Admin/Settings/
?? app/Livewire/Admin/Themes/
?? resources/views/livewire/admin/navigation/
?? resources/views/livewire/admin/pages/
?? resources/views/livewire/admin/settings/
?? resources/views/livewire/admin/themes/
?? tests/Feature/Admin/ContentManagementTest.php
?? tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: bfc26c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 67
Output:
 resources/views/layouts/app/sidebar.blade.php | 20 ++++++++++++++++
 routes/web.php                                | 17 ++++++++++++++
 specs/progress.md                             | 33 ++++++++++++++++++++-------
 3 files changed, 62 insertions(+), 8 deletions(-)


message: The only stray files are Playwright MCP logs/snapshots from the browser smoke run. I’m removing just those untracked generated files and leaving tracked project files alone.


text: The only stray files are Playwright MCP logs/snapshots from the browser smoke run. I’m removing just those untracked generated files and leaving tracked project files alone.


cmd: git ls-files --others --exclude-standard -z .playwright-mcp | xargs -0 rm -f


command: git ls-files --others --exclude-standard -z .playwright-mcp | xargs -0 rm -f


output:
Chunk ID: fb9e8d
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


cmd: find app/Livewire/Admin/Navigation app/Livewire/Admin/Pages app/Livewire/Admin/Settings app/Livewire/Admin/Themes resources/views/livewire/admin/navigation resources/views/livewire/admin/pages resources/views/livewire/admin/settings resources/views/livewire/admin/themes -type f | sort


aggregated_output:
 M resources/views/layouts/app/sidebar.blade.php
 M routes/web.php
 M specs/progress.md
?? app/Livewire/Admin/Navigation/
?? app/Livewire/Admin/Pages/
?? app/Livewire/Admin/Settings/
?? app/Livewire/Admin/Themes/
?? resources/views/livewire/admin/navigation/
?? resources/views/livewire/admin/pages/
?? resources/views/livewire/admin/settings/
?? resources/views/livewire/admin/themes/
?? tests/Feature/Admin/ContentManagementTest.php
?? tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: 8ab8ad
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 122
Output:
 M resources/views/layouts/app/sidebar.blade.php
 M routes/web.php
 M specs/progress.md
?? app/Livewire/Admin/Navigation/
?? app/Livewire/Admin/Pages/
?? app/Livewire/Admin/Settings/
?? app/Livewire/Admin/Themes/
?? resources/views/livewire/admin/navigation/
?? resources/views/livewire/admin/pages/
?? resources/views/livewire/admin/settings/
?? resources/views/livewire/admin/themes/
?? tests/Feature/Admin/ContentManagementTest.php
?? tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: 72a7e4
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 67
Output:
 resources/views/layouts/app/sidebar.blade.php | 20 ++++++++++++++++
 routes/web.php                                | 17 ++++++++++++++
 specs/progress.md                             | 33 ++++++++++++++++++++-------
 3 files changed, 62 insertions(+), 8 deletions(-)


command: find app/Livewire/Admin/Navigation app/Livewire/Admin/Pages app/Livewire/Admin/Settings app/Livewire/Admin/Themes resources/views/livewire/admin/navigation resources/views/livewire/admin/pages resources/views/livewire/admin/settings resources/views/livewire/admin/themes -type f | sort

path: Navigation


output:
Chunk ID: 8e8ec2
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 186
Output:
app/Livewire/Admin/Navigation/Index.php
app/Livewire/Admin/Pages/Form.php
app/Livewire/Admin/Pages/Index.php
app/Livewire/Admin/Settings/Index.php
app/Livewire/Admin/Settings/Shipping.php
app/Livewire/Admin/Settings/Taxes.php
app/Livewire/Admin/Themes/Editor.php
app/Livewire/Admin/Themes/Index.php
resources/views/livewire/admin/navigation/index.blade.php
resources/views/livewire/admin/pages/form.blade.php
resources/views/livewire/admin/pages/index.blade.php
resources/views/livewire/admin/settings/index.blade.php
resources/views/livewire/admin/settings/shipping.blade.php
resources/views/livewire/admin/settings/taxes.blade.php
resources/views/livewire/admin/themes/editor.blade.php
resources/views/livewire/admin/themes/index.blade.php


message: The working set is clean apart from this feature slice. I’m staging the Livewire components, Blade views, routes/sidebar updates, tests, and progress notes for a single coherent commit.


text: The working set is clean apart from this feature slice. I’m staging the Livewire components, Blade views, routes/sidebar updates, tests, and progress notes for a single coherent commit.


cmd: git add routes/web.php resources/views/layouts/app/sidebar.blade.php specs/progress.md app/Livewire/Admin/Navigation app/Livewire/Admin/Pages app/Livewire/Admin/Settings app/Livewire/Admin/Themes resources/views/livewire/admin/navigation resources/views/livewire/admin/pages resources/views/livewire/admin/settings resources/views/livewire/admin/themes tests/Feature/Admin/ContentManagementTest.php tests/Feature/Admin/SettingsManagementTest.php


command: git add routes/web.php resources/views/layouts/app/sidebar.blade.php specs/progress.md app/Livewire/Admin/Navigation app/Livewire/Admin/Pages app/Livewire/Admin/Settings app/Livewire/Admin/Themes resources/views/livewire/admin/navigation resources/views/livewire/admin/pages resources/views/livewire/admin/settings resources/views/livewire/admin/themes tests/Feature/Admin/ContentManagementTest.php tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: d0a99c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


command:
/bin/zsh
-lc
git diff --cached --check

cmd: git diff --cached --check


command:
/bin/zsh
-lc
git diff --cached --stat

cmd: git diff --cached --stat

aggregated_output:
 app/Livewire/Admin/Navigation/Index.php            | 315 +++++++++++++++++
 app/Livewire/Admin/Pages/Form.php                  | 174 ++++++++++
 app/Livewire/Admin/Pages/Index.php                 |  76 ++++
 app/Livewire/Admin/Settings/Index.php              | 260 ++++++++++++++
 app/Livewire/Admin/Settings/Shipping.php           | 384 +++++++++++++++++++++
 app/Livewire/Admin/Settings/Taxes.php              | 169 +++++++++
 app/Livewire/Admin/Themes/Editor.php               | 159 +++++++++
 app/Livewire/Admin/Themes/Index.php                | 154 +++++++++
 resources/views/layouts/app/sidebar.blade.php      |  20 ++
 .../livewire/admin/navigation/index.blade.php      | 100 ++++++
 .../views/livewire/admin/pages/form.blade.php      |  64 ++++
 .../views/livewire/admin/pages/index.blade.php     |  53 +++
 .../views/livewire/admin/settings/index.blade.php  | 145 ++++++++
 .../livewire/admin/settings/shipping.blade.php     | 163 +++++++++
 .../views/livewire/admin/settings/taxes.blade.php  |  71 ++++
 .../views/livewire/admin/themes/editor.blade.php   |  70 ++++
 .../views/livewire/admin/themes/index.blade.php    |  45 +++
 routes/web.php                                     |  17 +
 specs/progress.md                                  |  33 +-
 tests/Feature/Admin/ContentManagementTest.php      | 227 ++++++++++++
 tests/Feature/Admin/SettingsManagementTest.php     | 171 +++++++++
 21 files changed, 2862 insertions(+), 8 deletions(-)


aggregated_output:
A  app/Livewire/Admin/Navigation/Index.php
A  app/Livewire/Admin/Pages/Form.php
A  app/Livewire/Admin/Pages/Index.php
A  app/Livewire/Admin/Settings/Index.php
A  app/Livewire/Admin/Settings/Shipping.php
A  app/Livewire/Admin/Settings/Taxes.php
A  app/Livewire/Admin/Themes/Editor.php
A  app/Livewire/Admin/Themes/Index.php
M  resources/views/layouts/app/sidebar.blade.php
A  resources/views/livewire/admin/navigation/index.blade.php
A  resources/views/livewire/admin/pages/form.blade.php
A  resources/views/livewire/admin/pages/index.blade.php
A  resources/views/livewire/admin/settings/index.blade.php
A  resources/views/livewire/admin/settings/shipping.blade.php
A  resources/views/livewire/admin/settings/taxes.blade.php
A  resources/views/livewire/admin/themes/editor.blade.php
A  resources/views/livewire/admin/themes/index.blade.php
M  routes/web.php
M  specs/progress.md
A  tests/Feature/Admin/ContentManagementTest.php
A  tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: 2919aa
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 245
Output:
A  app/Livewire/Admin/Navigation/Index.php
A  app/Livewire/Admin/Pages/Form.php
A  app/Livewire/Admin/Pages/Index.php
A  app/Livewire/Admin/Settings/Index.php
A  app/Livewire/Admin/Settings/Shipping.php
A  app/Livewire/Admin/Settings/Taxes.php
A  app/Livewire/Admin/Themes/Editor.php
A  app/Livewire/Admin/Themes/Index.php
M  resources/views/layouts/app/sidebar.blade.php
A  resources/views/livewire/admin/navigation/index.blade.php
A  resources/views/livewire/admin/pages/form.blade.php
A  resources/views/livewire/admin/pages/index.blade.php
A  resources/views/livewire/admin/settings/index.blade.php
A  resources/views/livewire/admin/settings/shipping.blade.php
A  resources/views/livewire/admin/settings/taxes.blade.php
A  resources/views/livewire/admin/themes/editor.blade.php
A  resources/views/livewire/admin/themes/index.blade.php
M  routes/web.php
M  specs/progress.md
A  tests/Feature/Admin/ContentManagementTest.php
A  tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: 10eb51
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 364
Output:
 app/Livewire/Admin/Navigation/Index.php            | 315 +++++++++++++++++
 app/Livewire/Admin/Pages/Form.php                  | 174 ++++++++++
 app/Livewire/Admin/Pages/Index.php                 |  76 ++++
 app/Livewire/Admin/Settings/Index.php              | 260 ++++++++++++++
 app/Livewire/Admin/Settings/Shipping.php           | 384 +++++++++++++++++++++
 app/Livewire/Admin/Settings/Taxes.php              | 169 +++++++++
 app/Livewire/Admin/Themes/Editor.php               | 159 +++++++++
 app/Livewire/Admin/Themes/Index.php                | 154 +++++++++
 resources/views/layouts/app/sidebar.blade.php      |  20 ++
 .../livewire/admin/navigation/index.blade.php      | 100 ++++++
 .../views/livewire/admin/pages/form.blade.php      |  64 ++++
 .../views/livewire/admin/pages/index.blade.php     |  53 +++
 .../views/livewire/admin/settings/index.blade.php  | 145 ++++++++
 .../livewire/admin/settings/shipping.blade.php     | 163 +++++++++
 .../views/livewire/admin/settings/taxes.blade.php  |  71 ++++
 .../views/livewire/admin/themes/editor.blade.php   |  70 ++++
 .../views/livewire/admin/themes/index.blade.php    |  45 +++
 routes/web.php                                     |  17 +
 specs/progress.md                                  |  33 +-
 tests/Feature/Admin/ContentManagementTest.php      | 227 ++++++++++++
 tests/Feature/Admin/SettingsManagementTest.php     | 171 +++++++++
 21 files changed, 2862 insertions(+), 8 deletions(-)


output:
Chunk ID: 4a28a4
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


message: The staged diff is limited to the new admin management surfaces plus tests and progress tracking, and whitespace checks pass. I’m committing it now.


text: The staged diff is limited to the new admin management surfaces plus tests and progress tracking, and whitespace checks pass. I’m committing it now.


cmd: git commit -m "Add admin content and settings management"


command: git commit -m "Add admin content and settings management"

aggregated_output:
[2026-05-04-codex-5-5-goal 68f978d1] Add admin content and settings management
 21 files changed, 2862 insertions(+), 8 deletions(-)
 create mode 100644 app/Livewire/Admin/Navigation/Index.php
 create mode 100644 app/Livewire/Admin/Pages/Form.php
 create mode 100644 app/Livewire/Admin/Pages/Index.php
 create mode 100644 app/Livewire/Admin/Settings/Index.php
 create mode 100644 app/Livewire/Admin/Settings/Shipping.php
 create mode 100644 app/Livewire/Admin/Settings/Taxes.php
 create mode 100644 app/Livewire/Admin/Themes/Editor.php
 create mode 100644 app/Livewire/Admin/Themes/Index.php
 create mode 100644 resources/views/livewire/admin/navigation/index.blade.php
 create mode 100644 resources/views/livewire/admin/pages/form.blade.php
 create mode 100644 resources/views/livewire/admin/pages/index.blade.php
 create mode 100644 resources/views/livewire/admin/settings/index.blade.php
 create mode 100644 resources/views/livewire/admin/settings/shipping.blade.php
 create mode 100644 resources/views/livewire/admin/settings/taxes.blade.php
 create mode 100644 resources/views/livewire/admin/themes/editor.blade.php
 create mode 100644 resources/views/livewire/admin/themes/index.blade.php
 create mode 100644 tests/Feature/Admin/ContentManagementTest.php
 create mode 100644 tests/Feature/Admin/SettingsManagementTest.php


output:
Chunk ID: e1057d
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 332
Output:
[2026-05-04-codex-5-5-goal 68f978d1] Add admin content and settings management
 21 files changed, 2862 insertions(+), 8 deletions(-)
 create mode 100644 app/Livewire/Admin/Navigation/Index.php
 create mode 100644 app/Livewire/Admin/Pages/Form.php
 create mode 100644 app/Livewire/Admin/Pages/Index.php
 create mode 100644 app/Livewire/Admin/Settings/Index.php
 create mode 100644 app/Livewire/Admin/Settings/Shipping.php
 create mode 100644 app/Livewire/Admin/Settings/Taxes.php
 create mode 100644 app/Livewire/Admin/Themes/Editor.php
 create mode 100644 app/Livewire/Admin/Themes/Index.php
 create mode 100644 resources/views/livewire/admin/navigation/index.blade.php
 create mode 100644 resources/views/livewire/admin/pages/form.blade.php
 create mode 100644 resources/views/livewire/admin/pages/index.blade.php
 create mode 100644 resources/views/livewire/admin/settings/index.blade.php
 create mode 100644 resources/views/livewire/admin/settings/shipping.blade.php
 create mode 100644 resources/views/livewire/admin/settings/taxes.blade.php
 create mode 100644 resources/views/livewire/admin/themes/editor.blade.php
 create mode 100644 resources/views/livewire/admin/themes/index.blade.php
 create mode 100644 tests/Feature/Admin/ContentManagementTest.php
 create mode 100644 tests/Feature/Admin/SettingsManagementTest.php


message: That slice is committed as `68f978d1 Add admin content and settings management`. Next I’m moving into Phase 7, which the progress file now marks as search, analytics, apps, and webhooks; I’ll re-check the specs and current code before choosing the smallest complete implementation slice.


text: That slice is committed as `68f978d1 Add admin content and settings management`. Next I’m moving into Phase 7, which the progress file now marks as search, analytics, apps, and webhooks; I’ll re-check the specs and current code before choosing the smallest complete implementation slice.


step: Inspect Phase 7 specs and current implementation gaps

step: Implement a focused Phase 7 slice with tests

status: pending

step: Run formatter, tests, build/browser checks as needed

step: Update progress and commit the slice

explanation: Phase 6 content/settings/theme/navigation is committed. Continuing with the roadmap’s next missing area.


output: Plan updated


cmd: rg -n "Phase 7|search|analytics|webhooks|apps" specs/09-IMPLEMENTATION-ROADMAP.md specs/02-API-ROUTES.md specs/03-ADMIN-UI.md specs/04-STOREFRONT-UI.md specs/05-BUSINESS-LOGIC.md specs/01-DATABASE-SCHEMA.md


cmd: sed -n '1,160p' /Users/fabianwesner/Herd/shop/.agents/skills/laravel-best-practices/SKILL.md && sed -n '1,140p' /Users/fabianwesner/Herd/shop/.agents/skills/pest-testing/SKILL.md


output:
Chunk ID: 476eef
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 0
Output:


command:
/bin/zsh
-lc
sed -n '1,220p' specs/progress.md

progress.md

type: read

cmd: sed -n '1,220p' specs/progress.md

aggregated_output:
# Shop Build Progress

## Objective

Build a complete, self-contained Laravel shop system from `specs/*`, with implemented acceptance criteria mapped to evidence, passing automated checks, verified browser flows, independent QA, and meaningful commits.

## Current Status

- Status: in progress
- Active slice: Phase 7 - search/analytics/apps/webhooks
- Started from: Laravel Livewire/Fortify starter kit with no shop domain tables or models present
- Last updated: 2026-05-04

## Phased Plan

1. Foundation: SQLite config, tenancy tables/models/factories/seeders, store resolution middleware, store scoping, admin/customer auth foundations, policies, and Phase 1 tests.
2. Catalog: product, variant, inventory, collection, media schema/models/services, admin catalog CRUD, storefront browsing, and tests.
3. Storefront theme/layout: theme/page/navigation data, storefront layout, product/collection/search/page views, and smoke browser verification.
4. Cart/checkout/pricing: cart API/UI, discount, shipping, tax, checkout state machine, and tests.
5. Payments/orders/fulfillment: mock PSP, order creation, refunds, fulfillments, customer account order views, and tests.
6. Admin panel: dashboard and all admin list/form/detail pages from Spec 03, with Livewire/Flux interactions.
7. Search/analytics/apps/webhooks: SQLite search, event aggregation, developer token/webhook UI, delivery jobs, and tests.
8. Final verification: full Pest suite, Pint, frontend build, Playwright MCP customer/admin flows, independent QA, fixes, and completion audit.

## Acceptance Checklist

| Area | Criteria Source | Status | Evidence |
| --- | --- | --- | --- |
| Database schema | `specs/01-DATABASE-SCHEMA.md` | partial | Phase 1 tenancy/auth tables, Phase 2 catalog tables, Phase 3 theme/content/navigation tables, Phase 4 cart/checkout/pricing tables, and Phase 5 order/payment/fulfillment tables are implemented: customer_addresses, orders, order_lines, payments, refunds, fulfillments, fulfillment_lines. Search/analytics/app tables are still missing. |
| Routes/API | `specs/02-API-ROUTES.md` | partial | Phase 1 auth routes plus catalog/cart/order/customer/discount/content/settings UI routes exist: `/`, `/collections`, `/collections/{handle}`, `/products/{handle}`, `/cart`, `/checkout`, `/checkout/confirmation/{order}`, `/search`, `/pages/{handle}`, `/account`, `/account/orders/{order}`, `/admin/products`, `/admin/products/create`, `/admin/products/{product}/edit`, `/admin/collections`, `/admin/collections/create`, `/admin/collections/{collection}/edit`, `/admin/inventory`, `/admin/orders`, `/admin/orders/{order}`, `/admin/customers`, `/admin/customers/{customer}`, `/admin/discounts`, `/admin/discounts/create`, `/admin/discounts/{discount}/edit`, `/admin/pages`, `/admin/pages/create`, `/admin/pages/{page}/edit`, `/admin/navigation`, `/admin/themes`, `/admin/themes/{theme}/editor`, `/admin/settings`, `/admin/settings/shipping`, `/admin/settings/taxes`. Storefront REST API now includes cart line CRUD, checkout address/shipping/discount/payment-method selection, checkout payment completion, and token-gated order lookup under `/api/storefront/v1`. Admin REST API now includes store-scoped order list/detail, fulfillment creation, and refund creation under `/api/admin/v1/stores/{store}`. Storefront search/suggest, analytics, app/webhook APIs, and broader admin REST surfaces are still missing. |
| Admin UI | `specs/03-ADMIN-UI.md` | partial | Flux/Livewire admin shell now includes dashboard KPI/date-range reporting, catalog/product/collection/inventory management, order/customer/discount management, page index/form, navigation menu editor, theme grid, theme settings editor with iframe preview, general settings, domain management, shipping zone/rate management, and tax settings with auth protection and store scoping. Analytics/search/apps admin surfaces, checkout/notification settings tabs, advanced theme file editing, and product media upload UI are still missing. |
| Storefront UI | `specs/04-STOREFRONT-UI.md` | partial | Storefront layout, home, collections index/detail, product detail, search, breadcrumbs, price display, product cards, DB-backed pages, seeded navigation menus, cached theme settings, product add-to-cart persistence, cart drawer, cart page with discount and shipping estimates, checkout address/shipping/discount/payment-selection/order-submission UI, order confirmation, and customer order list/detail views render seeded and runtime data. |
| Business logic | `specs/05-BUSINESS-LOGIC.md` | partial | `ResolveStore`, `BelongsToStore`, `StoreScope`, role checks, customer guard provider, catalog product lifecycle transitions, SKU uniqueness, variant matrix rebuilding, inventory reserve/release/commit/restock, automatic variant inventory, variant option mapping, media resize/cleanup job, `CartService`, `DiscountService`, `ShippingCalculator`, `TaxCalculator`, `PricingEngine`, checkout transitions through completion, checkout expiration, abandoned …27675 chars truncated…vigation Blade/sidebar changes.
- 2026-05-04: `php artisan test --compact` passed after the admin content/settings/theme/navigation changes: 156 tests, 800 assertions.
- 2026-05-04: `php artisan migrate:fresh --seed --no-interaction` passed after browser verification to restore the local SQLite database to seeded fixtures.
- 2026-05-04: `mcp__laravel_boost__.get_absolute_url(path: "/admin/pages")` resolved `http://shop.test/admin/pages` before browser verification.
- 2026-05-04: Playwright MCP verified `http://shop.test/admin/pages`, `/admin/pages/create`, `/admin/navigation`, `/admin/settings`, `/admin/settings/shipping`, `/admin/settings/taxes`, `/admin/themes`, and `/admin/themes/1/editor`; browser smoke saved a page, added/saved a navigation item, rendered settings/shipping/tax pages, rendered the theme editor iframe preview, and current Playwright console checks reported no warnings/errors. Boost `browser_logs` only returned older May 3 account-login warnings from a previously fixed issue.

## Decisions

- Follow the roadmap order strictly. Phase 1 is required before catalog, checkout, admin, storefront, and QA flows can be meaningfully implemented.
- Preserve the starter Fortify conventions where they do not conflict with the shop specs.
- Use integer minor units for all money columns and JSON text columns cast through Eloquent as specified.
- Keep `password_hash` as the database column for admin users and customers while exposing `password`/`getAuthPassword()` at the model layer for Fortify/Laravel auth compatibility.
- Seed both `shop.test` and `acme-fashion.test` as storefront domains for the first store so the goal URL and E2E spec URL can both resolve.
- Customer Livewire auth components persist `storeId` from the initial storefront request because Livewire update requests do not run through the original storefront route middleware.
- The seed specification contains an arithmetic conflict: Acme Fashion's per-product variant table sums to 117 variants, while the prose says 107. The implementation follows the concrete per-product table, resulting in 117 Fashion variants and 10 Electronics variants, 127 total.
- Child catalog models without a `store_id` column are tenant-scoped through their parent product relationship. Inventory keeps its denormalized `store_id` and enforces that it matches the variant product store at save time.
- Storefront content pages now resolve from the `pages` table and only published pages are rendered.
- The catalog admin form intentionally blocks active products without a priced variant and duplicate in-store SKUs during UI edits, mirroring service-layer invariants where the current CRUD surface touches product variants directly.
- Navigation tree support is flat for now because the Phase 3 schema defines `navigation_items.position` but no `parent_id`; `NavigationService::buildTree()` returns a flat tree-compatible array with empty children.
- Cart, checkout, and pricing runtime records are not seeded; only deterministic tax, shipping, and discount configuration is seeded. Runtime carts/checkouts are created by services and tests.
- The cart drawer reads the current session/customer cart without creating an empty cart on every storefront render; carts are created on first add-to-cart or checkout/cart service mutation.
- The checkout UI reserves inventory by selecting a payment method, then submits payment through `CheckoutService::completeCheckout()` so failed card payments can release reservations and return customers to payment selection.
- Order confirmation access is allowed for the authenticated owning customer or for the session that just placed the order via `last_order_id`.
- Customer account order list/detail routes use the `customer` guard and reload orders through explicit store/customer constraints.
- The cart REST API exposes `cart_version` as the public optimistic concurrency field while the service layer keeps its `expectedVersion` argument; `expected_version` remains accepted as a compatibility alias in API requests.
- Cart page discount codes are validated with `DiscountService`, saved in session, and applied to the checkout when the customer proceeds.
- Admin discount forms persist minimum purchase, product eligibility, and collection eligibility in the existing `discounts.rules_json` keys consumed by `DiscountService`; `one_per_customer` is captured for future redemption-history enforcement.
- `PricingEngine` applies an explicit checkout discount code first, then active automatic discounts returned by `DiscountService`.
- `orders.checkout_id` is intentionally added beyond the original schema table to enforce idempotent checkout completion without duplicate orders.
- Failed card payments release reserved inventory and move the checkout back to `shipping_selected` so customers can retry payment selection.
- Bank transfer order completion creates a pending order and payment while keeping inventory reserved until the later admin payment-confirmation flow.


command: rg -n "Phase 7|search|analytics|webhooks|apps" specs/09-IMPLEMENTATION-ROADMAP.md specs/02-API-ROUTES.md specs/03-ADMIN-UI.md specs/04-STOREFRONT-UI.md specs/05-BUSINESS-LOGIC.md specs/01-DATABASE-SCHEMA.md

type: search

cmd: rg -n 'Phase 7|search|analytics|webhooks|apps' specs/09-IMPLEMENTATION-ROADMAP.md specs/02-API-ROUTES.md specs/03-ADMIN-UI.md specs/04-STOREFRONT-UI.md specs/05-BUSINESS-LOGIC.md specs/01-DATABASE-SCHEMA.md

query: Phase 7|search|analytics|webhooks|apps

aggregated_output:
specs/01-DATABASE-SCHEMA.md:492:### search_settings
specs/01-DATABASE-SCHEMA.md:494:Per-store search configuration (synonyms, stop words).
specs/01-DATABASE-SCHEMA.md:505:### search_queries
specs/01-DATABASE-SCHEMA.md:507:Search query log for analytics and autocomplete.
specs/01-DATABASE-SCHEMA.md:520:- `idx_search_queries_store_id` on (`store_id`) - FK lookup
specs/01-DATABASE-SCHEMA.md:521:- `idx_search_queries_store_created` on (`store_id`, `created_at`) - Time-range queries per store
specs/01-DATABASE-SCHEMA.md:522:- `idx_search_queries_store_query` on (`store_id`, `query`) - Autocomplete and popular search lookups
specs/01-DATABASE-SCHEMA.md:914:### analytics_events
specs/01-DATABASE-SCHEMA.md:916:Raw event stream for storefront analytics.
specs/01-DATABASE-SCHEMA.md:932:- `idx_analytics_events_store_id` on (`store_id`) - FK lookup
specs/01-DATABASE-SCHEMA.md:933:- `idx_analytics_events_store_type` on (`store_id`, `type`) - Filtering events by type per store
specs/01-DATABASE-SCHEMA.md:934:- `idx_analytics_events_store_created` on (`store_id`, `created_at`) - Time-range event queries
specs/01-DATABASE-SCHEMA.md:935:- `idx_analytics_events_session` on (`session_id`) - Session-based event grouping
specs/01-DATABASE-SCHEMA.md:936:- `idx_analytics_events_customer` on (`customer_id`) - Customer activity history
specs/01-DATABASE-SCHEMA.md:937:- `idx_analytics_events_client_event` UNIQUE on (`store_id`, `client_event_id`) - Client-side event deduplication
specs/01-DATABASE-SCHEMA.md:939:**Notes:** Event types include: `page_view`, `product_view`, `add_to_cart`, `remove_from_cart`, `checkout_started`, `checkout_completed`, `search`. This table will grow fast - consider periodic archiving or partitioning by date for production workloads beyond SQLite.
specs/01-DATABASE-SCHEMA.md:943:### analytics_daily
specs/01-DATABASE-SCHEMA.md:963:- `idx_analytics_daily_store_date` on (`store_id`, `date`) - Time-range metric queries (covered by PK but explicit for clarity)
specs/01-DATABASE-SCHEMA.md:971:### apps
specs/01-DATABASE-SCHEMA.md:984:- `idx_apps_status` on (`status`) - Filtering apps by status
specs/01-DATABASE-SCHEMA.md:996:| app_id | INTEGER | No | - | FK -> apps(id) ON DELETE CASCADE | |
specs/01-DATABASE-SCHEMA.md:1011:OAuth2 client credentials for apps.
specs/01-DATABASE-SCHEMA.md:1016:| app_id | INTEGER | No | - | FK -> apps(id) ON DELETE CASCADE | Parent app |
specs/01-DATABASE-SCHEMA.md:1432:    stores ||--o{ analytics_events : "records"
specs/01-DATABASE-SCHEMA.md:1433:    stores ||--o{ analytics_daily : "aggregates"
specs/01-DATABASE-SCHEMA.md:1434:    customers ||--o{ analytics_events : "generates"
specs/01-DATABASE-SCHEMA.md:1435:    apps ||--o{ app_installations : "installed via"
specs/01-DATABASE-SCHEMA.md:1437:    apps ||--o{ oauth_clients : "authenticates via"
specs/01-DATABASE-SCHEMA.md:1443:    analytics_events {
specs/01-DATABASE-SCHEMA.md:1449:    analytics_daily {
specs/01-DATABASE-SCHEMA.md:1455:    apps {
specs/01-DATABASE-SCHEMA.md:1515:        apps
specs/01-DATABASE-SCHEMA.md:1531:        search_settings
specs/01-DATABASE-SCHEMA.md:1551:        search_queries
specs/01-DATABASE-SCHEMA.md:1563:        analytics_events
specs/01-DATABASE-SCHEMA.md:1564:        analytics_daily
specs/01-DATABASE-SCHEMA.md:1581:    apps --> app_installations
specs/01-DATABASE-SCHEMA.md:1582:    apps --> oauth_clients
specs/01-DATABASE-SCHEMA.md:1591:    stores --> search_settings
specs/01-DATABASE-SCHEMA.md:1609:    stores --> search_queries
specs/01-DATABASE-SCHEMA.md:1624:    stores --> analytics_events
specs/01-DATABASE-SCHEMA.md:1625:    customers --> analytics_events
specs/01-DATABASE-SCHEMA.md:1626:    stores --> analytics_daily
specs/01-DATABASE-SCHEMA.md:1643:- **Batch 1** (no dependencies): `organizations`, `apps`
specs/01-DATABASE-SCHEMA.md:1645:- **Batch 3** (depends on Batch 2): `store_domains`, `store_users`, `store_settings`, `customers`, `themes`, `pages`, `navigation_menus`, `search_settings`, `shipping_zones`, `tax_settings`, `discounts`, `products`, `collections`, `app_installations`, `oauth_clients`
specs/01-DATABASE-SCHEMA.md:1646:- **Batch 4** (depends on Batch 3): `product_options`, `product_variants`, `product_media`, `collection_products`, `customer_addresses`, `carts`, `navigation_items`, `theme_files`, `theme_settings`, `search_queries`, `shipping_rates`, `oauth_tokens`, `webhook_subscriptions`
specs/01-DATABASE-SCHEMA.md:1647:- **Batch 5** (depends on Batch 4): `product_option_values`, `inventory_items`, `cart_lines`, `checkouts`, `orders`, `analytics_events`, `analytics_daily`, `webhook_deliveries`
specs/01-DATABASE-SCHEMA.md:1661:4. **Composite primary keys for pivot tables** - Tables like `store_users`, `collection_products`, `variant_option_values`, and `analytics_daily` use composite primary keys to naturally enforce uniqueness and serve as their own covering index for the most common query pattern.
specs/01-DATABASE-SCHEMA.md:1663:5. **Date-based indexes for time series** - Table…12733 chars truncated…d:1573:| logs search query for analytics | perform search | search_queries row created | happy path |
specs/09-IMPLEMENTATION-ROADMAP.md:1574:| paginates search results | 25 matching products, 12 per page | page 1 has 12, page 2 has 12, page 3 has 1 | happy path |
specs/09-IMPLEMENTATION-ROADMAP.md:1592:| tracks a page view event | POST analytics event: type=page_view | analytics_events row created | happy path |
specs/09-IMPLEMENTATION-ROADMAP.md:1604:| aggregates daily metrics from raw events | create events: 5 page_views, 3 add_to_carts, 2 checkout_completed; run AggregateAnalytics job | analytics_daily row with correct counts | happy path |
specs/09-IMPLEMENTATION-ROADMAP.md:1606:| runs idempotently | run aggregation twice for same date | analytics_daily row has correct values (not doubled) | edge case |
specs/09-IMPLEMENTATION-ROADMAP.md:1736:| `AnalyticsEvent` | Raw analytics event |
specs/09-IMPLEMENTATION-ROADMAP.md:1737:| `AnalyticsDaily` | Pre-aggregated daily analytics |
specs/09-IMPLEMENTATION-ROADMAP.md:1738:| `SearchSettings` | Per-store search configuration |
specs/09-IMPLEMENTATION-ROADMAP.md:1848:| `AggregateAnalytics` | Daily analytics aggregation |
specs/09-IMPLEMENTATION-ROADMAP.md:1944:- Configure rate limiters: `login` (5/min per IP), `api.admin` (60/min per token), `api.storefront` (120/min per IP), `checkout` (10/min per session), `search` (30/min per IP), `analytics` (60/min per IP), `webhooks` (100/min per IP)
specs/03-ADMIN-UI.md:95:Analytics                        -> admin.analytics.index
specs/03-ADMIN-UI.md:97:Apps                             -> admin.apps.index
specs/03-ADMIN-UI.md:232:| `loadKpis()` | Queries aggregated order/analytics data |
specs/03-ADMIN-UI.md:349:| `search` | `string` | Search query, live-debounced at 300ms |
specs/03-ADMIN-UI.md:371:| `products` | Paginated query result with search, filters, sorting applied. Eager loads `variants`, `media` (limit 1). Uses `withCount('variants')`. |
specs/03-ADMIN-UI.md:380:| [search icon] Search products...   [Status: All v] [Type: All v] |
specs/03-ADMIN-UI.md:714:| `search` | `string` | Search query |
specs/03-ADMIN-UI.md:724:| `collections` | Paginated, filtered, searched. Includes `withCount('products')`. |
specs/03-ADMIN-UI.md:773:| `searchResults` | Products matching `productSearch` that are not already assigned |
specs/03-ADMIN-UI.md:831:| `search` | `string` | Search by product title or SKU |
specs/03-ADMIN-UI.md:836:| `inventoryItems` | Paginated inventory items with variant and product eager loaded, filtered by search and stock level |
specs/03-ADMIN-UI.md:844:| [search] Search by product or SKU   [Stock: All v]               |
specs/03-ADMIN-UI.md:874:| `search` | `string` | Search by order number or customer email |
specs/03-ADMIN-UI.md:887:| `orders` | Paginated query with search, status filter, sorting. Eager loads `customer`. |
specs/03-ADMIN-UI.md:895:| [search] Search by order # or email...                           |
specs/03-ADMIN-UI.md:1148:| `search` | `string` | Search by name or email |
specs/03-ADMIN-UI.md:1152:| `customers` | Paginated, searched customers with `withCount('orders')` and `withSum('orders', 'total_amount')` |
specs/03-ADMIN-UI.md:1247:| `search` | `string` | Search by discount code |
specs/03-ADMIN-UI.md:1361:- Specific products: search input with live debounce. Results appear in a scrollable dropdown. Selected products shown as a list with remove (X) buttons.
specs/03-ADMIN-UI.md:1759:|            |  |                        | |  Show search:        |
specs/03-ADMIN-UI.md:1817:| `search` | `string` | Search by page title |
specs/03-ADMIN-UI.md:1959:**Route:** `GET /admin/apps`
specs/03-ADMIN-UI.md:1963:**Blade view:** `resources/views/livewire/admin/apps/index.blade.php`
specs/03-ADMIN-UI.md:2005:**Empty state:** "No apps installed" with descriptive text.
specs/03-ADMIN-UI.md:2022:| `webhooks` | `Collection` | Webhook subscriptions |
specs/03-ADMIN-UI.md:2117:- Endpoint URL input (type: url, placeholder: "https://example.com/webhooks")
specs/03-ADMIN-UI.md:2124:**Route:** `GET /admin/analytics`
specs/03-ADMIN-UI.md:2128:**Blade view:** `resources/views/livewire/admin/analytics/index.blade.php`
specs/03-ADMIN-UI.md:2151:| `updatedDateRange()` | Reloads analytics data |
specs/03-ADMIN-UI.md:2154:| `loadAnalytics()` | Master method to reload all analytics data |
specs/03-ADMIN-UI.md:2211:**Route:** `GET /admin/search/settings`
specs/03-ADMIN-UI.md:2215:**Blade view:** `resources/views/livewire/admin/search/settings.blade.php`
specs/03-ADMIN-UI.md:2252:| Words that are excluded from search indexing.                    |
specs/03-ADMIN-UI.md:2425:| `App\Livewire\Admin\Apps\Index` | `livewire.admin.apps.index` | `GET /admin/apps` |
specs/03-ADMIN-UI.md:2427:| `App\Livewire\Admin\Analytics\Index` | `livewire.admin.analytics.index` | `GET /admin/analytics` |
specs/03-ADMIN-UI.md:2428:| `App\Livewire\Admin\Search\Settings` | `livewire.admin.search.settings` | `GET /admin/search/settings` |