<command-name>/config</command-name>
            <command-message>config</command-message>
            <command-args></command-args>


<local-command-stdout>Status dialog dismissed</local-command-stdout>


<command-name>/mcp</command-name>
            <command-message>mcp</command-message>
            <command-args></command-args>


<local-command-stdout>MCP dialog dismissed</local-command-stdout>


# Mission

Implement a complete shop system based on the specifications in `specs/*`. Do not stop until all phases are complete, all requirements are implemented, all acceptance criteria are met, and all 143 test cases pass verification.

Before starting, read the team mode documentation: https://code.claude.com/docs/en/agent-teams
You must use team mode (not sub-agents).

---

# Phases & Sequencing

- Phases are defined in `specs/*`. Read all spec files before creating the project plan.
- Phases are developed strictly sequentially. No parallel development.
- Only one phase is active at a time.
- For each phase, spawn a fresh team (details below). Do not reuse teammates across phases.
- After all phases: run Final E2E QA, then Adversarial QA, then fix any issues, then re-run E2E QA until clean.

---

# Team Composition

For each phase, the team lead spawns the following roles. All teammates except the Controller are replaced per phase to keep context fresh.

| Role | Scope | Persists across phases? |
|---|---|---|
| **Team Lead** | Management, supervision, delegation. Does no coding, reviewing, or verification. | Yes |
| **Controller** | Artifact auditor with veto power. Does not code, run tools, or use Playwright. Works exclusively from markdown artifacts and team lead reports. Enforces rigor by catching incomplete, ambiguous, or sloppy reporting. | Yes |
| **BDD Expert** | Writes Gherkin specs from the phase requirements. | No (fresh per phase) |
| **Gherkin Reviewer** | Confirms Gherkin specs are 100% complete vs. the phase spec, and consistent with preceding/succeeding phases. | No (fresh per phase) |
| **Developers** (1+, specialized as needed: backend, frontend, schema, etc.) | Implementation using TDD with Pest. Follow the prepared Gherkin specs. No Pest tests required for pure UI work. | No (fresh per phase) |
| **Code Reviewer** | Reviews code for clean code, SOLID, Laravel best practices. Runs static analysis (phpmetrics or similar) for duplication, vulnerabilities, complexity. Produces a quality report as markdown. | No (fresh per phase) |
| **QA Analyst** | Verifies functionality non-scripted using Playwright and Chrome. Tests all routes AND rendered pages (not just route existence). Tracks all checks in a markdown file. | No (fresh per phase) |

### Available tooling

All teammates must use the available MCP servers:
- **Laravel Boost** (MCP server, already configured)
- **PHP LSP** (MCP server, already configured)

The Code Reviewer additionally uses phpmetrics or equivalent for static analysis.

---

# Artifact Requirements

Every teammate must document their work in markdown files. These artifacts are the Controller's sole input. If it's not written down, it didn't happen.

### General rules for all artifacts
- Every artifact must include: **what** was done, **how** it was done, **why** decisions were made, and an **honest self-assessment** of the work (including uncertainties, risks, or areas of concern).
- No artifact may contain only checklists or status tables. There must be prose that explains the reasoning.
- Ambiguous statuses (UNKNOWN, SKIPPED, PARTIAL, N/A, blank) are not permitted. Every item is PASS or FAIL. If something could not be verified, that is a FAIL with an explanation.

### Per-role artifact specifications

**BDD Expert** writes `work/phase-{N}/gherkin-specs.md`:
- List of every acceptance criterion from the phase spec, each mapped to one or more Gherkin scenarios.
- Traceability table: spec requirement ID/description -> Gherkin scenario name.
- Self-assessment: Are there any requirements that were ambiguous or hard to translate? How were they interpreted and why?

**Gherkin Reviewer** writes `work/phase-{N}/gherkin-review.md`:
- Confirmation that every spec requirement has a corresponding Gherkin scenario (with the count).
- Check for consistency with preceding and succeeding phases.
- List of any concerns, ambiguities, or gaps found (even if resolved).
- Self-assessment: Confidence level in completeness. What could be missing? Were any edge cases intentionally excluded and why?

**Developers** write `work/phase-{N}/dev-report.md`:
- What was implemented and how (architecture decisions, patterns used).
- List of Pest test cases created, mapped to Gherkin scenarios.
- Any deviations from the Gherkin specs and why.
- Known limitations or technical debt introduced.
- Self-assessment: What are the weakest parts of this implementation? What would break first under load or edge cases?

**Code Reviewer** writes `work/phase-{N}/code-review.md`:
- Quality metrics defined upfront (what was measured and what thresholds were set).
- Item-level checklist with PASS/FAIL per item.
- Static analysis results (phpmetrics or equivalent) with key numbers.
- For any finding that was fixed: what the issue was, how it was fixed, and confirmation it was re-checked.
- Self-assessment: Overall code quality rating with justification. What are the remaining risks? Is there anything that passed the checklist but still feels fragile?

**QA Analyst** writes `work/phase-{N}/qa-report.md`:
- Every Gherkin scenario mapped to a verification entry.
- For each entry: what was tested, how it was tested (specific Playwright actions), what the expected result was, what the actual result was, and PASS/FAIL.
- For any FAIL that was fixed and re-tested: the original failure, what was fixed, and the re-test result.
- **Asset verification section**: Every page visited must be checked for broken images, missing assets, and broken links. Document each page URL, the number of images/assets found, how many loaded successfully, and PASS/FAIL. If a product image is referenced but doesn't render, that is a FAIL.
- **URL verification section**: Every internal link and navigation element across all pages must be clicked and verified. Document each URL, expected destination, actual result (page loaded / 404 / error / redirect), and PASS/FAIL.
- Regression check: confirmation that previous phase functionality still works.
- Self-assessment: Are there areas that felt undertested? Anything that passed but seemed brittle? Any concerns about behavior that technically meets the spec but feels wrong?

**UAT Analyst** writes `work/final-e2e-qa.md`:
- All 143 test cases with the same detail level as QA Analyst entries above (what, how, expected, actual, PASS/FAIL).
- Self-assessment section at the end.

**Adversarial QA Analyst** writes `work/adversarial-qa.md`:
- Edge cases tested, organized by the baseline test case they extend.
- For each: what was tried, what the expected behavior was, what actually happened, and PASS/FAIL.
- Log file inspection results (any exceptions or errors found).
- Self-assessment: How hard did you try to break it? What attack vectors were explored? What remains untested?

---

# Per-Phase Workflow

Every phase follows this exact sequence:

### 1. BDD Specification
- The **BDD Expert** rewrites the phase requirements into Gherkin specs.
- The **Gherkin Reviewer** confirms the specs are complete, correct, and consistent with adjacent phases.
- The **Controller** approves the Gherkin specs before any coding begins.

### 2. Implementation (TDD)
- The **Team Lead** decides which specialized developer teammates to spawn.
- Developers implement using TDD with Pest, driven by the approved Gherkin specs.
- Pure UI work is exempt from Pest tests but must still follow the specs.

### 3. Code Review
- The **Code Reviewer** reviews all code from the phase.
- Must create a checklist, define quality metrics, and produce results as a markdown report.
- Uses Laravel Boost, PHP LSP, and phpmetrics (or equivalent).
- Code must follow clean code, SOLID, and Laravel best practices.
- No code duplication, no vulnerabilities, no syntax errors.

### 4. QA Verification
- The **QA Analyst** verifies all functionality non-scripted using Playwright and Chrome.
- All links, routes, and rendered pages must work. Route existence alone is insufficient.
- All checks are tracked in a phase-specific markdown file.
- Every check must PASS. No gaps, no compromises, no skipped cases.
- If bugs are found: developers fix them, then the QA Analyst re-verifies.

### 5. Controller Sign-Off

The **Controller** does not look at code, does not run Playwright, and does not use any tooling directly. The Controller works exclusively from the markdown artifacts produced by other teammates and from statements by the Team Lead. The Controller's job is to catch laziness, sloppiness, or incompleteness in other agents' work by auditing the quality and honesty of their documentation.

The Controller reviews the following artifacts and applies these acceptance criteria. Every criterion must be MET. If any criterion is NOT MET, the Controller issues a veto and the relevant step is re-executed.

**A. Gherkin Specs** (`work/phase-{N}/gherkin-specs.md` and `work/phase-{N}/gherkin-review.md`)
- [ ] Both files exist.
- [ ] The traceability table maps every spec requirement to a Gherkin scenario. None are missing.
- [ ] The Gherkin Reviewer's report provides a written confirmation with the exact count of requirements vs. scenarios.
- [ ] Both artifacts contain self-assessments that are substantive (not just "everything looks good"). If the self-assessment raises concerns, those concerns must be addressed or acknowledged.

**B. Dev Report** (`work/phase-{N}/dev-report.md`)
- [ ] The report exists and explains what was built and how.
- [ ] Pest test cases are listed and mapped to Gherkin scenarios.
- [ ] Any deviations from spec are documented with reasoning.
- [ ] The self-assessment section exists and is honest (identifies weaknesses, not just confirms success).

**C. Code Review Report** (`work/phase-{N}/code-review.md`)
- [ ] The report exists with quality metrics, thresholds, and item-level PASS/FAIL.
- [ ] Every item is PASS. No UNKNOWN, SKIPPED, PARTIAL, or blank.
- [ ] Static analysis results are included with actual numbers (not just "passed").
- [ ] The self-assessment provides an overall quality rating with justification and identifies remaining risks.
- [ ] If any finding was initially FAIL: the fix and re-check are documented.

**D. QA Report** (`work/phase-{N}/qa-report.md`)
- [ ] The report exists with an entry for every Gherkin scenario.
- [ ] Every entry describes what was tested, how (Playwright actions), expected vs. actual result, and PASS/FAIL.
- [ ] Every entry is PASS. No UNKNOWN, SKIPPED, PARTIAL, N/A, or blank.
- [ ] If any entry was initially FAIL: the failure, fix, and re-test are all documented.
- [ ] The report contains an **asset verification section** listing every page, the number of images/assets found, how many loaded, and PASS/FAIL per page. No missing or broken images allowed.
- [ ] The report contains a **URL verification section** listing every internal link and navigation element, the expected destination, the actual result, and PASS/FAIL. No 404s, broken links, or dead-end navigation allowed.
- [ ] Regression check for previous phases is documented.
- [ ] The self-assessment is substantive and flags any concerns, even if everything passed.

**E. Completeness & Consistency**
- [ ] The number of Gherkin scenarios matches or exceeds the number of spec requirements.
- [ ] The number of QA entries matches or exceeds the number of Gherkin scenarios.
- [ ] The number of Pest tests matches or exceeds the number of Gherkin scenarios (excluding pure UI).
- [ ] No requirement is unaccounted for across the chain: spec -> Gherkin -> dev -> code review -> QA.
- [ ] Self-assessments across all artifacts are consistent (no contradictions, e.g. dev says "this is fragile" but QA says "no concerns").

**F. Artifact Quality**
- [ ] No artifact is a bare checklist without explanatory prose.
- [ ] Every artifact contains a self-assessment section with honest evaluation.
- [ ] If any self-assessment raises a risk or concern, it has been either resolved (with evidence) or explicitly accepted with justification by the Team Lead.

If all criteria are MET, the Controller produces `work/signoff-phase-{N}.md` containing the filled checklist above with status per item, plus a brief narrative assessment of the phase. Development of the next phase may only begin after this sign-off.

### 6. Progress Tracking
- The **Team Lead** updates `work/progress.md` and makes a git commit with a meaningful message after each phase.

---

# Final E2E QA

After all phases are complete:

1. The Team Lead spawns a **fresh UAT Analyst** (not reused from any phase).
2. The UAT Analyst executes all 143 test cases from `specs/08-PLAYWRIGHT-E2E-PLAN.md` using Playwright and Chrome.
3. Verification is non-scripted (agent-driven, not pre-written test scripts).
4. Every test case must be executed. No skipping.
5. All results are tracked in `work/final-e2e-qa.md` with pass/fail per test case.
6. If any test case fails: developers fix the issue, then the UAT Analyst re-verifies.
7. The **Controller** reviews `work/final-e2e-qa.md` and applies these acceptance criteria:
    - [ ] The file contains exactly 143 test case entries (matching `specs/08-PLAYWRIGHT-E2E-PLAN.md`).
    - [ ] Every entry describes what was tested, how, expected vs. actual, and has an explicit PASS status.
    - [ ] No FAIL, UNKNOWN, SKIPPED, PARTIAL, N/A, or blank entries.
    - [ ] If any test was initially FAIL: the failure, fix, and re-test with PASS are all documented.
    - [ ] No test case IDs from the E2E plan are missing.
    - [ ] The file contains a self-assessment section at the end.
    - [ ] Cross-reference: 143 unique IDs, 143 PASS results.

---

# Adversarial QA

After the Final E2E QA passes:

1. The Team Lead spawns one **Adversarial QA Analyst**.
2. This analyst takes the existing 143 test cases as a baseline and tests edge cases around them.
3. The goal is to break the system: malformed input, broken URLs, missing routes, unexpected navigation, boundary conditions.
4. The analyst also inspects log files for unhandled exceptions or errors.
5. All findings are tracked in `work/adversarial-qa.md`.
6. If issues are found: developers fix them, then a fresh Final E2E QA round is run (all 143 test cases again).
7. This cycle repeats until the system is clean.

---

# Final Sign-Off

The **Controller** produces `work/final-signoff.md` only after verifying every item below. Each item must reference the specific artifact file that proves it.

- [ ] All phase sign-off files exist (`work/signoff-phase-{N}.md` for every phase) and every checklist item within them is MET.
- [ ] All per-phase artifacts exist in `work/phase-{N}/` (gherkin-specs, gherkin-review, dev-report, code-review, qa-report) for every phase.
- [ ] `work/final-e2e-qa.md` exists, contains 143 test cases all with PASS status, and includes a self-assessment.
- [ ] `work/adversarial-qa.md` exists, all findings are resolved (no open issues), and includes a self-assessment.
- [ ] If a fix cycle occurred after adversarial QA: a subsequent E2E QA round was executed and all 143 test cases passed again.
- [ ] `work/progress.md` is up to date and reflects all phases as complete.
- [ ] No markdown artifact anywhere in the project contains UNKNOWN, SKIPPED, PARTIAL, N/A, or blank statuses.
- [ ] Every artifact contains a substantive self-assessment (not just "all good").
- [ ] No self-assessment raises an unresolved concern.

Only after this sign-off is the project complete.

---

# Team Lead Responsibilities

- Read all specs before creating the project plan. Have the Controller approve the plan.
- Keep `work/progress.md` current. Git commit with a meaningful message after every relevant iteration. Ensure a final commit at the end.
- Spawn and manage teammates per the rules above. Stay focused on management and supervision.
- **Do not** code, review, verify, or research directly. Delegate everything.
- Consult the Controller after every phase and before closing the project.


I'll start by reading the team mode documentation and all spec files to understand the full scope before creating a plan.


ToolSearch

Question: select:WebFetch,TeamCreate,TaskCreate,TaskList,TaskUpdate,TaskGet,SendMessage,EnterPlanMode


WebFetch TeamCreate TaskCreate TaskList TaskUpdate TaskGet SendMessage EnterPlanMode

Question: select:WebFetch,TeamCreate,TaskCreate,TaskList,TaskUpdate,TaskGet,SendMessage,EnterPlanMode


Let me read the team mode docs and all spec files in parallel.


WebFetch

Prompt: Extract all documentation about how agent teams work in Claude Code. Include: how to create teams, spawn teammates, assign tasks, coordinate work, best practices, and any limitations or constraints.


> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Orchestrate teams of Claude Code sessions

> Coordinate multiple Claude Code instances working together as a team, with shared tasks, inter-agent messaging, and centralized management.

<Warning>
  Agent teams are experimental and disabled by default. Enable them by adding `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` to your [settings.json](/en/settings) or environment. Agent teams have [known limitations](#limitations) around session resumption, task coordination, and shutdown behavior.
</Warning>

Agent teams let you coordinate multiple Claude Code instances working together. One session acts as the team lead, coordinating work, assigning tasks, and synthesizing results. Teammates work independently, each in its own context window, and communicate directly with each other.

Unlike [subagents](/en/sub-agents), which run within a single session and can only report back to the main agent, you can also interact with individual teammates directly without going through the lead.

<Note>
  Agent teams require Claude Code v2.1.32 or later. Check your version with `claude --version`.
</Note>

This page covers:

* [When to use agent teams](#when-to-use-agent-teams), including best use cases and how they compare with subagents
* [Starting a team](#start-your-first-agent-team)
* [Controlling teammates](#control-your-agent-team), including display modes, task assignment, and delegation
* [Best practices for parallel work](#best-practices)

## When to use agent teams

Agent teams are most effective for tasks where parallel exploration adds real value. See [use case examples](#use-case-examples) for full scenarios. The strongest use cases are:

* **Research and review**: multiple teammates can investigate different aspects of a problem simultaneously, then share and challenge each other's findings
* **New modules or features**: teammates can each own a separate piece without stepping on each other
* **Debugging with competing hypotheses**: teammates test different theories in parallel and converge on the answer faster
* **Cross-layer coordination**: changes that span frontend, backend, and tests, each owned by a different teammate

Agent teams add coordination overhead and use significantly more tokens than a single session. They work best when teammates can operate independently. For sequential tasks, same-file edits, or work with many dependencies, a single session or [subagents](/en/sub-agents) are more effective.

### Compare with subagents

Both agent teams and [subagents](/en/sub-agents) let you parallelize work, but they operate differently. Choose based on whether your workers need to communicate with each other:

<Frame caption="Subagents only report results back to the main agent and never talk to each other. In agent teams, teammates share a task list, claim work, and communicate directly with each other.">
  <img src="https://mintcdn.com/claude-code/nsvRFSDNfpSU5nT7/images/subagents-vs-agent-teams-light.png?fit=max&auto=format&n=nsvRFSDNfpSU5nT7&q=85&s=2f8db9b4f3705dd3ab931fbe2d96e42a" className="dark:hidden" alt="Diagram comparing subagent and agent team architectures. Subagents are spawned by the main agent, do work, and report results back. Agent teams coordinate through a shared task list, with teammates communicating directly with each other." width="4245" height="1615" data-path="images/subagents-vs-agent-teams-light.png" />

  <img src="https://mintcdn.com/claude-code/nsvRFSDNfpSU5nT7/images/subagents-vs-agent-teams-dark.png?fit=max&auto=format&n=nsvRFSDNfpSU5nT7&q=85&s=d573a037540f2ada6a9ae7d8285b46fd" className="hidden dark:block" alt="Diagram comparing subagent and agent team architectures. Subagents are spawned by the main agent, do work, and report results back. Agent teams coordinate through a shared task list, with teammates communicating directly with each other." width="4245" height="1615" data-path="images/subagents-vs-agent-teams-dark.png" />
</Frame>

|                   | Subagents                                        | Agent teams                                         |
| :---------------- | :----------------------------------------------- | :-------------------------------------------------- |
| **Context**       | Own context window; results return to the caller | Own context window; fully independent               |
| **Communication** | Report results back to the main agent only       | Teammates message each other directly               |
| **Coordination**  | Main agent manages all work                      | Shared task list with self-coordination             |
| **Best for**      | Focused tasks where only the result matters      | Complex work requiring discussion and collaboration |
| **Token cost**    | Lower: results summarized back to main context   | Higher: each teammate is a separate Claude instance |

Use subagents when you need quick, focused workers that report back. Use agent teams when teammates need to share findings, challenge each other, and coordinate on their own.

## Enable agent teams

Agent teams are disabled by default. Enable them by setting the `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` environment variable to `1`, either in your shell environment or through [settings.json](/en/settings):

```json settings.json theme={null}
{
  "env": {
    "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
  }
}
```

## Start your first agent team

After enabling agent teams, tell Claude to create an agent team and describe the task and the team structure you want in natural language. Claude creates the team, spawns teammates, and coordinates work based on your prompt.

This example works well because the three roles are independent and can explore the problem without waiting on each other:

```text  theme={null}
I'm designing a CLI tool that helps developers track TODO comments across
their codebase. Create an agent team to explore this from different angles: one
teammate on UX, one on technical architecture, one playing devil's advocate.
```

From there, Claude creates a team with a [shared task list](/en/interactive-mode#task-list), spawns teammates for each perspective, has them explore the problem, synthesizes findings, and attempts to [clean up the team](#clean-up-the-team) when finished.

The lead's terminal lists all teammates and what they're working on. Use Shift+Down to cycle through teammates and message them directly. After the last teammate, Shift+Down wraps back to the lead.

If you want each teammate in its own split pane, see [Choose a display mode](#choose-a-display-mode).

## Control your agent team

Tell the lead what you want in natural language. It handles team coordination, task assignment, and delegation based on your instructions.

### Choose a display mode

Agent teams support two display modes:

* **In-process**: all teammates run inside your main terminal. Use Shift+Down to cycle through teammates and type to message them directly. Works in any terminal, no extra setup required.
* **Split panes**: each teammate gets its own pane. You can see everyone's output at once and click into a pane to interact directly. Requires tmux, or iTerm2.

<Note>
  `tmux` has known limitations on certain operating systems and traditionally works best on macOS. Using `tmux -CC` in iTerm2 is the suggested entrypoint into `tmux`.
</Note>

The default is `"auto"`, which uses split panes if you're already running inside a tmux session, and in-process otherwise. The `"tmux"` setting enables split-pane mode and auto-detects whether to use tmux or iTerm2 based on your terminal. To override, set `teammateMode` in your [settings.json](/en/settings):

```json  theme={null}
{
  "teammateMode": "in-process"
}
```

To force in-process mode for a single session, pass it as a flag:

```bash  theme={null}
claude --teammate-mode in-process
```

Split-pane mode requires either [tmux](https://github.com/tmux/tmux/wiki) or iTerm2 with the [`it2` CLI](https://github.com/mkusaka/it2). To install manually:

* **tmux**: install through your system's package manager. See the [tmux wiki](https://github.com/tmux/tmux/wiki/Installing) for platform-specific instructions.
* **iTerm2**: install the [`it2` CLI](https://github.com/mkusaka/it2), then enable the Python API in **iTerm2 → Settings → General → Magic → Enable Python API**.

### Specify teammates and models

Claude decides the number of teammates to spawn based on your task, or you can specify exactly what you want:

```text  theme={null}
Create a team with 4 teammates to refactor these modules in parallel.
Use Sonnet for each teammate.
```

### Require plan approval for teammates

For complex or risky tasks, you can require teammates to plan before implementing. The teammate works in read-only plan mode until the lead approves their approach:

```text  theme={null}
Spawn an architect teammate to refactor the authentication module.
Require plan approval before they make any changes.
```

When a teammate finishes planning, it sends a plan approval request to the lead. The lead reviews the plan and either approves it or rejects it with feedback. If rejected, the teammate stays in plan mode, revises based on the feedback, and resubmits. Once approved, the teammate exits plan mode and begins implementation.

The lead makes approval decisions autonomously. To influence the lead's judgment, give it criteria in your prompt, such as "only approve plans that include test coverage" or "reject plans that modify the database schema."

### Talk to teammates directly

Each teammate is a full, independent Claude Code session. You can message any teammate directly to give additional instructions, ask follow-up questions, or redirect their approach.

* **In-process mode**: use Shift+Down to cycle through teammates, then type to send them a message. Press Enter to view a teammate's session, then Escape to interrupt their current turn. Press Ctrl+T to toggle the task list.
* **Split-pane mode**: click into a teammate's pane to interact with their session directly. Each teammate has a full view of their own terminal.

### Assign and claim tasks

The shared task list coordinates work across the team. The lead creates tasks and teammates work through them. Tasks have three states: pending, in progress, and completed. Tasks can also depend on other tasks: a pending task with unresolved dependencies cannot be claimed until those dependencies are completed.

The lead can assign tasks explicitly, or teammates can self-claim:

* **Lead assigns**: tell the lead which task to give to which teammate
* **Self-claim**: after finishing a task, a teammate picks up the next unassigned, unblocked task on its own

Task claiming uses file locking to prevent race conditions when multiple teammates try to claim the same task simultaneously.

### Shut down teammates

To gracefully end a teammate's session:

```text  theme={null}
Ask the researcher teammate to shut down
```

The lead sends a shutdown request. The teammate can approve, exiting gracefully, or reject with an explanation.

### Clean up the team

When you're done, ask the lead to clean up:

```text  theme={null}
Clean up the team
```

This removes the shared team resources. When the lead runs cleanup, it checks for active teammates and fails if any are still running, so shut them down first.

<Warning>
  Always use the lead to clean up. Teammates should not run cleanup because their team context may not resolve correctly, potentially leaving resources in an inconsistent state.
</Warning>

### Enforce quality gates with hooks

Use [hooks](/en/hooks) to enforce rules when teammates finish work or tasks complete:

* [`TeammateIdle`](/en/hooks#teammateidle): runs when a teammate is about to go idle. Exit with code 2 to send feedback and keep the teammate working.
* [`TaskCompleted`](/en/hooks#taskcompleted): runs when a task is being marked complete. Exit with code 2 to prevent completion and send feedback.

## How agent teams work

This section covers the architecture and mechanics behind agent teams. If you want to start using them, see [Control your agent team](#control-your-agent-team) above.

### How Claude starts agent teams

There are two ways agent teams get started:

* **You request a team**: give Claude a task that benefits from parallel work and explicitly ask for an agent team. Claude creates one based on your instructions.
* **Claude proposes a team**: if Claude determines your task would benefit from parallel work, it may suggest creating a team. You confirm before it proceeds.

In both cases, you stay in control. Claude won't create a team without your approval.

### Architecture

An agent team consists of:

| Component     | Role                                                                                |
| :------------ | :----------------------------------------------------------------------------------------- |
| **Team lead** | The main Claude Code session that creates the team, spawns teammates, and coordinates work |
| **Teammates** | Separate Claude Code instances that each work on assigned tasks                            |
| **Task list** | Shared list of work items that teammates claim and complete                                |
| **Mailbox**   | Messaging system for communication between agents                                          |

See [Choose a display mode](#choose-a-display-mode) for display configuration options. Teammate messages arrive at the lead automatically.

The system manages task dependencies automatically. When a teammate completes a task that other tasks depend on, blocked tasks unblock without manual intervention.

Teams and tasks are stored locally:

* **Team config**: `~/.claude/teams/{team-name}/config.json`
* **Task list**: `~/.claude/tasks/{team-name}/`

The team config contains a `members` array with each teammate's name, agent ID, and agent type. Teammates can read this file to discover other team members.

### Permissions

Teammates start with the lead's permission settings. If the lead runs with `--dangerously-skip-permissions`, all teammates do too. After spawning, you can change individual teammate modes, but you can't set per-teammate modes at spawn time.

### Context and communication

Each teammate has its own context window. When spawned, a teammate loads the same project context as a regular session: CLAUDE.md, MCP servers, and skills. It also receives the spawn prompt from the lead. The lead's conversation history does not carry over.

**How teammates share information:**

* **Automatic message delivery**: when teammates send messages, they're delivered automatically to recipients. The lead doesn't need to poll for updates.
* **Idle notifications**: when a teammate finishes and stops, they automatically notify the lead.
* **Shared task list**: all agents can see task status and claim available work.

**Teammate messaging:**

* **message**: send a message to one specific teammate
* **broadcast**: send to all teammates simultaneously. Use sparingly, as costs scale with team size.

### Token usage

Agent teams use significantly more tokens than a single session. Each teammate has its own context window, and token usage scales with the number of active teammates. For research, review, and new feature work, the extra tokens are usually worthwhile. For routine tasks, a single session is more cost-effective. See [agent team token costs](/en/costs#agent-team-token-costs) for usage guidance.

## Use case examples

These examples show how agent teams handle tasks where parallel exploration adds value.

### Run a parallel code review

A single reviewer tends to gravitate toward one type of issue at a time. Splitting review criteria into independent domains means security, performance, and test coverage all get thorough attention simultaneously. The prompt assigns each teammate a distinct lens so they don't overlap:

```text  theme={null}
Create an agent team to review PR #142. Spawn three reviewers:
- One focused on security implications
- One checking performance impact
- One validating test coverage
Have them each review and report findings.
```

Each reviewer works from the same PR but applies a different filter. The lead synthesizes findings across all three after they finish.

### Investigate with competing hypotheses

When the root cause is unclear, a single agent tends to find one plausible explanation and stop looking. The prompt fights this by making teammates explicitly adversarial: each one's job is not only to investigate its own theory but to challenge the others'.

```text  theme={null}
Users report the app exits after one message instead of staying connected.
Spawn 5 agent teammates to investigate different hypotheses. Have them talk to
each other to try to disprove each other's theories, like a scientific
debate. Update the findings doc with whatever consensus emerges.
```

The debate structure is the key mechanism here. Sequential investigation suffers from anchoring: once one theory is explored, subsequent investigation is biased toward it.

With multiple independent investigators actively trying to disprove each other, the theory that survives is much more likely to be the actual root cause.

## Best practices

### Give teammates enough context

Teammates load project context automatically, including CLAUDE.md, MCP servers, and skills, but they don't inherit the lead's conversation history. See [Context and communication](#context-and-communication) for details. Include task-specific details in the spawn prompt:

```text  theme={null}
Spawn a security reviewer teammate with the prompt: "Review the authentication module
at src/auth/ for security vulnerabilities. Focus on token handling, session
management, and input validation. The app uses JWT tokens stored in
httpOnly cookies. Report any issues with severity ratings."
```

### Choose an appropriate team size

There's no hard limit on the number of teammates, but practical constraints apply:

* **Token costs scale linearly**: each teammate has its own context window and consumes tokens independently. See [agent team token costs](/en/costs#agent-team-token-costs) for details.
* **Coordination overhead increases**: more teammates means more communication, task coordination, and potential for conflicts
* **Diminishing returns**: beyond a certain point, additional teammates don't speed up work proportionally

Start with 3-5 teammates for most workflows. This balances parallel work with manageable coordination. The examples in this guide use 3-5 teammates because that range works well across different task types.

Having 5-6 [tasks](/en/agent-teams#architecture) per teammate keeps everyone productive without excessive context switching. If you have 15 independent tasks, 3 teammates is a good starting point.

Scale up only when the work genuinely benefits from having teammates work simultaneously. Three focused teammates often outperform five scattered ones.

### Size tasks appropriately

* **Too small**: coordination overhead exceeds the benefit
* **Too large**: teammates work too long without check-ins, increasing risk of wasted effort
* **Just right**: self-contained units that produce a clear deliverable, such as a function, a test file, or a review

<Tip>
  The lead breaks work into tasks and assigns them to teammates automatically. If it isn't creating enough tasks, ask it to split the work into smaller pieces. Having 5-6 tasks per teammate keeps everyone productive and lets the lead reassign work if someone gets stuck.
</Tip>

### Wait for teammates to finish

Sometimes the lead starts implementing tasks itself instead of waiting for teammates. If you notice this:

```text  theme={null}
Wait for your teammates to complete their tasks before proceeding
```

### Start with research and review

If you're new to agent teams, start with tasks that have clear boundaries and don't require writing code: reviewing a PR, researching a library, or investigating a bug. These tasks show the value of parallel exploration without the coordination challenges that come with parallel implementation.

### Avoid file conflicts

Two teammates editing the same file leads to overwrites. Break the work so each teammate owns a different set of files.

### Monitor and steer

Check in on teammates' progress, redirect approaches that aren't working, and synthesize findings as they come in. Letting a team run unattended for too long increases the risk of wasted effort.

## Troubleshooting

### Teammates not appearing

If teammates aren't appearing after you ask Claude to create a team:

* In in-process mode, teammates may already be running but not visible. Press Shift+Down to cycle through active teammates.
* Check that the task you gave Claude was complex enough to warrant a team. Claude decides whether to spawn teammates based on the task.
* If you explicitly requested split panes, ensure tmux is installed and available in your PATH:
  ```bash  theme={null}
  which tmux
  ```
* For iTerm2, verify the `it2` CLI is installed and the Python API is enabled in iTerm2 preferences.

### Too many permission prompts

Teammate permission requests bubble up to the lead, which can create friction. Pre-approve common operations in your [permission settings](/en/permissions) before spawning teammates to reduce interruptions.

### Teammates stopping on errors

Teammates may stop after encountering errors instead of recovering. Check their output using Shift+Down in in-process mode or by clicking the pane in split mode, then either:

* Give them additional instructions directly
* Spawn a replacement teammate to continue the work

### Lead shuts down before work is done

The lead may decide the team is finished before all tasks are actually complete. If this happens, tell it to keep going. You can also tell the lead to wait for teammates to finish before proceeding if it starts doing work instead of delegating.

### Orphaned tmux sessions

If a tmux session persists after the team ends, it may not have been fully cleaned up. List sessions and kill the one created by the team:

```bash  theme={null}
tmux ls
tmux kill-session -t <session-name>
```

## Limitations

Agent teams are experimental. Current limitations to be aware of:

* **No session resumption with in-process teammates**: `/resume` and `/rewind` do not restore in-process teammates. After resuming a session, the lead may attempt to message teammates that no longer exist. If this happens, tell the lead to spawn new teammates.
* **Task status can lag**: teammates sometimes fail to mark tasks as completed, which blocks dependent tasks. If a task appears stuck, check whether the work is actually done and update the task status manually or tell the lead to nudge the teammate.
* **Shutdown can be slow**: teammates finish their current request or tool call before shutting down, which can take time.
* **One team per session**: a lead can only manage one team at a time. Clean up the current team before starting a new one.
* **No nested teams**: teammates cannot spawn their own teams or teammates. Only the lead can manage the team.
* **Lead is fixed**: the session that creates the team is the lead for its lifetime. You can't promote a teammate to lead or transfer leadership.
* **Permissions set at spawn**: all teammates start with the lead's permission mode. You can change individual teammate modes after spawning, but you can't set per-teammate modes at spawn time.
* **Split panes require tmux or iTerm2**: the default in-process mode works in any terminal. Split-pane mode isn't supported in VS Code's integrated terminal, Windows Terminal, or Ghostty.

<Tip>
  **`CLAUDE.md` works normally**: teammates read `CLAUDE.md` files from their working directory. Use this to provide project-specific guidance to all teammates.
</Tip>

## Next steps

Explore related approaches for parallel work and delegation:

* **Lightweight delegation**: [subagents](/en/sub-agents) spawn helper agents for research or verification within your session, better for tasks that don't need inter-agent coordination
* **Manual parallel sessions**: [Git worktrees](/en/common-workflows#run-parallel-claude-code-sessions-with-git-worktrees) let you run multiple Claude Code sessions yourself without automated team coordination
* **Compare approaches**: see the [subagent vs agent team](/en/features-overview#compare-similar-features) comparison for a side-by-side breakdown


Error: File content (32506 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (20509 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (29197 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (27031 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (18315 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (19155 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (14269 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (22558 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


Error: File content (26132 tokens) exceeds maximum allowed tokens (10000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.


The spec files are large. Let me read them in chunks, starting with the implementation roadmap (the most critical one for planning).


     1→# 09 - Implementation Roadmap and Pest Test Specification
     2→
     3→> E-commerce platform - Step-by-step build order and exhaustive test plan for Laravel 12 + Livewire v4 + Flux UI Free + SQLite + Tailwind CSS v4
     4→
     5→---
     6→
     7→## 1. Technology Decisions (Final)
     8→
     9→These decisions adapt the original PDF spec for a self-contained, benchmarkable Laravel application. All decisions are final and must not be revisited.
    10→
    11→| Concern | PDF Default | Our Decision | Rationale |
    12→|---------|-------------|--------------|-----------|
    13→| Database | PostgreSQL | SQLite | Self-contained, no external DB, zero config |
    14→| Cache | Redis | File (Array for tests) | No Redis dependency |
    15→| Session | Redis | File | No Redis dependency |
    16→| Queue | Redis + Horizon | Sync (dev) / Database (prod) | No Redis dependency, sync for immediate feedback |
    17→| Search | Elasticsearch + Scout | SQLite FTS5 | Self-contained, no external service |
    18→| Storage | S3 | Local filesystem (storage/app/public) | No AWS dependency |
    19→| Admin UI | React/Vue SPA | Livewire v4 + Flux UI Free | Server-rendered, matches project stack |
    20→| Storefront | Blade SSR + Vite | Blade + Livewire + Tailwind v4 | Server-rendered, matches project stack |
    21→| Auth (admin) | Sanctum SPA | Laravel session auth | Standard Livewire auth pattern |
    22→| Auth (API) | Sanctum tokens | Sanctum personal access tokens | For programmatic API access |
    23→| Auth (customer) | Separate guard | Custom `customer` guard | Storefront customer auth |
    24→| OAuth (apps) | Passport | Deferred/Stubbed | Simplifies initial build, can add later |
    25→| Payments | Stripe + PayPal | Mock PSP (in-process) | No external API calls. MockPaymentProvider handles credit card, PayPal, bank transfer with magic card numbers for testing. |
    26→| Email | SMTP/SES | Log driver (dev) / SMTP | Log for benchmark, SMTP configurable |
    27→| Monitoring | OpenTelemetry | Laravel Log (structured JSON) | Simplified for benchmark |
    28→| CI/CD | GitHub Actions | Not implemented | Out of scope for one-shot benchmark |
    29→| Docker | Multi-stage | Not implemented | App served by Laravel Herd locally |
    30→
    31→---
    32→
    33→## 2. Implementation Phases (Build Order)
    34→
    35→Each phase builds on the previous. A coding agent should execute these in strict sequential order. Tests are written alongside each phase (see Section 3 for the full test specification).
    36→
    37→### Phase Dependency Graph
    38→
    39→```mermaid
    40→flowchart TD
    41→    P1[Phase 1: Foundation]
    42→    P2[Phase 2: Catalog]
    43→    P3[Phase 3: Themes and Storefront Layout]
    44→    P4[Phase 4: Cart, Checkout, Discounts, Shipping, Taxes]
    45→    P5[Phase 5: Payments, Orders, Fulfillment]
    46→    P6[Phase 6: Customer Accounts]
    47→    P7[Phase 7: Admin Panel]
    48→    P8[Phase 8: Search]
    49→    P9[Phase 9: Analytics]
    50→    P10[Phase 10: Apps and Webhooks]
    51→    P11[Phase 11: Polish]
    52→    P12[Phase 12: Full Test Suite]
    53→
    54→    P1 --> P2
    55→    P1 --> P3
    56→    P2 --> P4
    57→    P3 --> P4
    58→    P4 --> P5
    59→    P5 --> P6
    60→    P5 --> P7
    61→    P2 --> P8
    62→    P5 --> P9
    63→    P5 --> P10
    64→    P6 --> P11
    65→    P7 --> P11
    66→    P8 --> P11
    67→    P9 --> P11
    68→    P10 --> P11
    69→    P11 --> P12
    70→```
    71→
    72→---
    73→
    74→### Phase 1: Foundation (Migrations, Models, Middleware, Auth)
    75→
    76→**Priority:** CRITICAL - everything depends on this.
    77→
    78→#### Step 1.1: Environment and Config
    79→
    80→| Config File | Setting | Value | Purpose |
    81→|-------------|---------|-------|---------|
    82→| `.env` | `DB_CONNECTION` | `sqlite` | Use SQLite as database |
    83→| `.env` | `DB_DATABASE` | `database/database.sqlite` | SQLite database file path |
    84→| `.env` | `CACHE_STORE` | `file` | File-based caching |
    85→| `.env` | `SESSION_DRIVER` | `file` | File-based sessions |
    86→| `.env` | `QUEUE_CONNECTION` | `sync` | Synchronous queue for dev |
    87→| `.env` | `MAIL_MAILER` | `log` | Log-based mail for dev |
    88→| `.env` | `FILESYSTEM_DISK` | `local` | Local filesystem storage |
    89→| `config/database.php` | SQLite connection | WAL mode, foreign keys enabled, busy_timeout=5000, synchronous=normal | Optimized SQLite configuration |
    90→| `config/session.php` | `driver` | `file` | Session driver |
    91→| `config/session.php` | `lifetime` | `120` | Session lifetime in minutes |
    92→| `config/cache.php` | `default` | `file` | Cache driver |
    93→| `config/queue.php` | `default` | `sync` | Queue driver |
    94→| `config/auth.php` | Guards | Add `customer` guard with `customers` provider | Customer storefront authentication |
    95→| `config/auth.php` | Providers | Add `customers` provider pointing to Customer model | Customer user provider |
    96→| `config/auth.php` | Passwords | Add `customers` password broker | Customer password reset |
    97→| `config/filesystems.php` | `public` disk | Ensure configured for local storage | Media file storage |
    98→| `config/logging.php` | Channels | Add structured JSON channel | Structured logging |
    99→
   100→#### Step 1.2: Core Migrations (Batch 1-2)
   101→
   102→Create in this dependency order:
   103→
   104→1. `create_organizations_table` - no dependencies
   105→2. `create_stores_table` - FK: `organization_id`
   106→3. `create_store_domains_table` - FK: `store_id`
   107→4. Modify default `users` migration - add `status`, `last_login_at`, `two_factor_*` columns; rename `password` to `password_hash` internally
   108→5. `create_store_users_table` - composite PK: `store_id` + `user_id`, with `role` column
   109→6. `create_store_settings_table` - PK: `store_id`
   110→
   111→All monetary amounts stored as INTEGER in minor units (cents). All enums stored as TEXT with CHECK constraints. All timestamps as TEXT (ISO-8601) via Laravel.
   112→
   113→#### Step 1.3: Core Models
   114→
   115→**Files to create:**
   116→
   117→| Type | Name | Purpose |
   118→|------|------|---------|
   119→| Model (with migration, factory, seeder) | `Organization` | Top-level tenant entity |
   120→| Model (with migration, factory, seeder) | `Store` | Individual store within an organization |
   121→| Model (with migration, factory, seeder) | `StoreDomain` | Domain mapping for a store |
   122→| Model (pivot) | `StoreUser` | Pivot model with `role` attribute, custom Pivot class |
   123→| Model (with migration, factory, seeder) | `StoreSettings` | Per-store configuration |
   124→
   125→**Relationship definitions:**
   126→
   127→| Model | Key Relationships |
   128→|-------|-------------------|
   129→| `Organization` | `hasMany(Store::class)` |
   130→| `Store` | `belongsTo(Organization::class)`, `hasMany(StoreDomain::class)`, `belongsToMany(User::class)` through `store_users`, `hasOne(StoreSettings::class)` |
   131→| `StoreDomain` | `belongsTo(Store::class)` |
   132→| `User` | `belongsToMany(Store::class)` through `store_users` |
   133→| `StoreUser` | Pivot model with `role` attribute, custom `Pivot` class |
   134→| `StoreSettings` | `belongsTo(Store::class)` |
   135→
   136→Each model must have:
   137→- Explicit return type declarations on all methods
   138→- Proper `$fillable` or `$guarded` arrays
   139→- `casts()` method for JSON/enum columns
   140→- Factory with meaningful default values
   141→- Seeder that creates sample data
   142→
   143→#### Step 1.4: Enums
   144→
   145→**Files to create in `app/Enums/`:**
   146→
   147→| Enum | Values |
   148→|------|--------|
   149→| `StoreStatus` | `Active`, `Suspended` |
   150→| `StoreUserRole` | `Owner`, `Admin`, `Staff`, `Support` |
   151→| `StoreDomainType` | `Storefront`, `Admin`, `Api` |
   152→
   153→#### Step 1.5: Tenant Resolution Middleware
   154→
   155→**File to create:** `App\Http\Middleware\ResolveStore`
   156→
   157→Requirements:
   158→1. Storefront routes: extract hostname from the request, look up `store_domains`, cache hostname-to-store_id for 5 minutes, bind `Store` as singleton via container instance `current_store`
   159→2. Admin routes: read `current_store_id` from session, verify user has `store_users` record
   160→3. Return 404 if hostname not found
   161→4. Return 503 for suspended stores on storefront routes
   162→
   163→**Registration in `bootstrap/app.php`:**
   164→- Register middleware group `storefront` containing `ResolveStore`
   165→- Register middleware group `admin` containing `ResolveStore`
   166→
   167→#### Step 1.6: BelongsToStore Trait and Global Scope
   168→
   169→**Files to create:**
   170→
   171→| Type | Name | Purpose |
   172→|------|------|---------|
   173→| Trait | `App\Models\Concerns\BelongsToStore` | Applies StoreScope and auto-sets store_id on creating event |
   174→| Scope | `App\Models\Scopes\StoreScope` | Applies `where('store_id', app('current_store')->id)` to all queries |
   175→
   176→Applied on: products, collections, customers, orders, carts, checkouts, discounts, shipping_zones, themes, pages, navigation_menus, analytics_events, analytics_daily, webhook_subscriptions, inventory_items, search_queries.
   177→
   178→#### Step 1.7: Authentication
   179→
   180→**Admin auth requirements:**
   181→
   182→| Component | Description |
   183→|-----------|-------------|
   184→| Livewire component `Admin\Auth\Login` | Admin login form |
   185→| Livewire component `Admin\Auth\Logout` | Admin logout action |
   186→| Auth mechanism | Standard Laravel session auth via `Auth::guard('web')->attempt()` |
   187→| Rate limiting | 5 attempts per minute per IP via `RateLimiter::for('login')` |
   188→| Password reset | Standard Laravel flow with `Password::broker('users')` |
   189→
   190→**Customer auth requirements:**
   191→
   192→| Component | Description |
   193→|-----------|-------------|
   194→| Custom guard | `customer` guard with `customers` provider |
   195→| Custom user provider | `CustomerUserProvider` that injects `store_id` into queries |
   196→| Livewire component `Storefront\Account\Auth\Login` | Customer login form |
   197→| Livewire component `Storefront\Account\Auth\Register` | Customer registration form |
   198→| Uniqueness | Customer email unique per store, not globally |
   199→| Rate limiting | 5 attempts per minute per IP |
   200→

# 09 - Implementation Roadmap and Pest Test Specification

> E-commerce platform - Step-by-step build order and exhaustive test plan for Laravel 12 + Livewire v4 + Flux UI Free + SQLite + Tailwind CSS v4

---

## 1. Technology Decisions (Final)

These decisions adapt the original PDF spec for a self-contained, benchmarkable Laravel application. All decisions are final and must not be revisited.

| Concern | PDF Default | Our Decision | Rationale |
|---------|-------------|--------------|-----------|
| Database | PostgreSQL | SQLite | Self-contained, no external DB, zero config |
| Cache | Redis | File (Array for tests) | No Redis dependency |
| Session | Redis | File | No Redis dependency |
| Queue | Redis + Horizon | Sync (dev) / Database (prod) | No Redis dependency, sync for immediate feedback |
| Search | Elasticsearch + Scout | SQLite FTS5 | Self-contained, no external service |
| Storage | S3 | Local filesystem (storage/app/public) | No AWS dependency |
| Admin UI | React/Vue SPA | Livewire v4 + Flux UI Free | Server-rendered, matches project stack |
| Storefront | Blade SSR + Vite | Blade + Livewire + Tailwind v4 | Server-rendered, matches project stack |
| Auth (admin) | Sanctum SPA | Laravel session auth | Standard Livewire auth pattern |
| Auth (API) | Sanctum tokens | Sanctum personal access tokens | For programmatic API access |
| Auth (customer) | Separate guard | Custom `customer` guard | Storefront customer auth |
| OAuth (apps) | Passport | Deferred/Stubbed | Simplifies initial build, can add later |
| Payments | Stripe + PayPal | Mock PSP (in-process) | No external API calls. MockPaymentProvider handles credit card, PayPal, bank transfer with magic card numbers for testing. |
| Email | SMTP/SES | Log driver (dev) / SMTP | Log for benchmark, SMTP configurable |
| Monitoring | OpenTelemetry | Laravel Log (structured JSON) | Simplified for benchmark |
| CI/CD | GitHub Actions | Not implemented | Out of scope for one-shot benchmark |
| Docker | Multi-stage | Not implemented | App served by Laravel Herd locally |

---

## 2. Implementation Phases (Build Order)

Each phase builds on the previous. A coding agent should execute these in strict sequential order. Tests are written alongside each phase (see Section 3 for the full test specification).

### Phase Dependency Graph

```mermaid
flowchart TD
    P1[Phase 1: Foundation]
    P2[Phase 2: Catalog]
    P3[Phase 3: Themes and Storefront Layout]
    P4[Phase 4: Cart, Checkout, Discounts, Shipping, Taxes]
    P5[Phase 5: Payments, Orders, Fulfillment]
    P6[Phase 6: Customer Accounts]
    P7[Phase 7: Admin Panel]
    P8[Phase 8: Search]
    P9[Phase 9: Analytics]
    P10[Phase 10: Apps and Webhooks]
    P11[Phase 11: Polish]
    P12[Phase 12: Full Test Suite]

    P1 --> P2
    P1 --> P3
    P2 --> P4
    P3 --> P4
    P4 --> P5
    P5 --> P6
    P5 --> P7
    P2 --> P8
    P5 --> P9
    P5 --> P10
    P6 --> P11
    P7 --> P11
    P8 --> P11
    P9 --> P11
    P10 --> P11
    P11 --> P12
```

---

### Phase 1: Foundation (Migrations, Models, Middleware, Auth)

**Priority:** CRITICAL - everything depends on this.

#### Step 1.1: Environment and Config

| Config File | Setting | Value | Purpose |
|-------------|---------|-------|---------|
| `.env` | `DB_CONNECTION` | `sqlite` | Use SQLite as database |
| `.env` | `DB_DATABASE` | `database/database.sqlite` | SQLite database file path |
| `.env` | `CACHE_STORE` | `file` | File-based caching |
| `.env` | `SESSION_DRIVER` | `file` | File-based sessions |
| `.env` | `QUEUE_CONNECTION` | `sync` | Synchronous queue for dev |
| `.env` | `MAIL_MAILER` | `log` | Log-based mail for dev |
| `.env` | `FILESYSTEM_DISK` | `local` | Local filesystem storage |
| `config/database.php` | SQLite connection | WAL mode, foreign keys enabled, busy_timeout=5000, synchronous=normal | Optimized SQLite configuration |
| `config/session.php` | `driver` | `file` | Session driver |
| `config/session.php` | `lifetime` | `120` | Session lifetime in minutes |
| `config/cache.php` | `default` | `file` | Cache driver |
| `config/queue.php` | `default` | `sync` | Queue driver |
| `config/auth.php` | Guards | Add `customer` guard with `customers` provider | Customer storefront authentication |
| `config/auth.php` | Providers | Add `customers` provider pointing to Customer model | Customer user provider |
| `config/auth.php` | Passwords | Add `customers` password broker | Customer password reset |
| `config/filesystems.php` | `public` disk | Ensure configured for local storage | Media file storage |
| `config/logging.php` | Channels | Add structured JSON channel | Structured logging |

#### Step 1.2: Core Migrations (Batch 1-2)

Create in this dependency order:

1. `create_organizations_table` - no dependencies
2. `create_stores_table` - FK: `organization_id`
3. `create_store_domains_table` - FK: `store_id`
4. Modify default `users` migration - add `status`, `last_login_at`, `two_factor_*` columns; rename `password` to `password_hash` internally
5. `create_store_users_table` - composite PK: `store_id` + `user_id`, with `role` column
6. `create_store_settings_table` - PK: `store_id`

All monetary amounts stored as INTEGER in minor units (cents). All enums stored as TEXT with CHECK constraints. All timestamps as TEXT (ISO-8601) via Laravel.

#### Step 1.3: Core Models

**Files to create:**

| Type | Name | Purpose |
|------|------|---------|
| Model (with migration, factory, seeder) | `Organization` | Top-level tenant entity |
| Model (with migration, factory, seeder) | `Store` | Individual store within an organization |
| Model (with migration, factory, seeder) | `StoreDomain` | Domain mapping for a store |
| Model (pivot) | `StoreUser` | Pivot model with `role` attribute, custom Pivot class |
| Model (with migration, factory, seeder) | `StoreSettings` | Per-store configuration |

**Relationship definitions:**

| Model | Key Relationships |
|-------|-------------------|
| `Organization` | `hasMany(Store::class)` |
| `Store` | `belongsTo(Organization::class)`, `hasMany(StoreDomain::class)`, `belongsToMany(User::class)` through `store_users`, `hasOne(StoreSettings::class)` |
| `StoreDomain` | `belongsTo(Store::class)` |
| `User` | `belongsToMany(Store::class)` through `store_users` |
| `StoreUser` | Pivot model with `role` attribute, custom `Pivot` class |
| `StoreSettings` | `belongsTo(Store::class)` |

Each model must have:
- Explicit return type declarations on all methods
- Proper `$fillable` or `$guarded` arrays
- `casts()` method for JSON/enum columns
- Factory with meaningful default values
- Seeder that creates sample data

#### Step 1.4: Enums

**Files to create in `app/Enums/`:**

| Enum | Values |
|------|--------|
| `StoreStatus` | `Active`, `Suspended` |
| `StoreUserRole` | `Owner`, `Admin`, `Staff`, `Support` |
| `StoreDomainType` | `Storefront`, `Admin`, `Api` |

#### Step 1.5: Tenant Resolution Middleware

**File to create:** `App\Http\Middleware\ResolveStore`

Requirements:
1. Storefront routes: extract hostname from the request, look up `store_domains`, cache hostname-to-store_id for 5 minutes, bind `Store` as singleton via container instance `current_store`
2. Admin routes: read `current_store_id` from session, verify user has `store_users` record
3. Return 404 if hostname not found
4. Return 503 for suspended stores on storefront routes

**Registration in `bootstrap/app.php`:**
- Register middleware group `storefront` containing `ResolveStore`
- Register middleware group `admin` containing `ResolveStore`

#### Step 1.6: BelongsToStore Trait and Global Scope

**Files to create:**

| Type | Name | Purpose |
|------|------|---------|
| Trait | `App\Models\Concerns\BelongsToStore` | Applies StoreScope and auto-sets store_id on creating event |
| Scope | `App\Models\Scopes\StoreScope` | Applies `where('store_id', app('current_store')->id)` to all queries |

Applied on: products, collections, customers, orders, carts, checkouts, discounts, shipping_zones, themes, pages, navigation_menus, analytics_events, analytics_daily, webhook_subscriptions, inventory_items, search_queries.

#### Step 1.7: Authentication

**Admin auth requirements:**

| Component | Description |
|-----------|-------------|
| Livewire component `Admin\Auth\Login` | Admin login form |
| Livewire component `Admin\Auth\Logout` | Admin logout action |
| Auth mechanism | Standard Laravel session auth via `Auth::guard('web')->attempt()` |
| Rate limiting | 5 attempts per minute per IP via `RateLimiter::for('login')` |
| Password reset | Standard Laravel flow with `Password::broker('users')` |

**Customer auth requirements:**

| Component | Description |
|-----------|-------------|
| Custom guard | `customer` guard with `customers` provider |
| Custom user provider | `CustomerUserProvider` that injects `store_id` into queries |
| Livewire component `Storefront\Account\Auth\Login` | Customer login form |
| Livewire component `Storefront\Account\Auth\Register` | Customer registration form |
| Uniqueness | Customer email unique per store, not globally |
| Rate limiting | 5 attempts per minute per IP |


     1→# 08 - Playwright E2E Test Plan
     2→
     3→> Complete end-to-end browser test specification for the e-commerce platform using Pest v4 browser testing (Playwright-backed). All tests verify the entire application works through a real browser. This document defines requirements and specifications for the coding agent to implement.
     4→
     5→---
     6→
     7→## Test Suite Summary
     8→
     9→| Suite | File | Tests | Purpose | Dependencies |
    10→|-------|------|:-----:|---------|--------------|
    11→| 1 - Smoke Tests | `tests/Browser/SmokeTest.php` | 10 | Hit every major page, assert HTTP 200 and no JS errors | Store 1, Products, Collections, Pages |
    12→| 2 - Admin Authentication | `tests/Browser/Admin/AuthenticationTest.php` | 10 | Admin login, logout, invalid credentials, session access control | Admin user |
    13→| 3 - Admin Product Management | `tests/Browser/Admin/ProductManagementTest.php` | 7 | Product CRUD: listing, creating, editing, archiving, filtering | Admin user, Products (incl. #15 draft) |
    14→| 4 - Admin Order Management | `tests/Browser/Admin/OrderManagementTest.php` | 11 | Order listing, filtering, detail view, fulfillment, refund, confirm payment, fulfillment guard, mark shipped/delivered | Admin user, Orders (#1001, #1005), Customer |
    15→| 5 - Admin Discount Management | `tests/Browser/Admin/DiscountManagementTest.php` | 6 | Discount code listing, creation, editing | Admin user, Discounts |
    16→| 6 - Admin Settings | `tests/Browser/Admin/SettingsTest.php` | 7 | Store settings, shipping zones, tax config, domains | Admin user, Shipping zones, Store 1 |
    17→| 7 - Storefront Browsing | `tests/Browser/Storefront/BrowsingTest.php` | 15 | Home page, collections, product detail, variants, search, pages | Products, Collections, Pages, Products #15/#17/#18 |
    18→| 8 - Cart Flow | `tests/Browser/Storefront/CartTest.php` | 12 | Cart lifecycle: add, update qty, remove, discounts, totals | Products, Discounts (all codes) |
    19→| 9 - Checkout Flow | `tests/Browser/Storefront/CheckoutTest.php` | 13 | Full checkout: contact, address, shipping, payment method selection, payment, confirmation, magic card decline, bank transfer flow | Products, Shipping zones, Discounts |
    20→| 10 - Customer Account | `tests/Browser/Storefront/CustomerAccountTest.php` | 12 | Registration, login, order history, addresses, logout | Customer user, Orders (#1001/#1002/#1004) |
    21→| 11 - Inventory Enforcement | `tests/Browser/Storefront/InventoryTest.php` | 4 | Inventory policy enforcement: deny vs. continue | Products #17 (deny), #18 (continue), #1 |
    22→| 12 - Tenant Isolation | `tests/Browser/Storefront/TenantIsolationTest.php` | 5 | Multi-store data isolation verification | Store 1, Admin user, Customer user |
    23→| 13 - Responsive / Mobile | `tests/Browser/Storefront/ResponsiveTest.php` | 8 | Mobile and tablet viewport rendering and interaction | Products, Admin user |
    24→| 14 - Accessibility | `tests/Browser/Storefront/AccessibilityTest.php` | 11 | Heading hierarchy, ARIA labels, form labels, keyboard nav | Products, Store 1 |
    25→| 15 - Admin Collections | `tests/Browser/Admin/CollectionManagementTest.php` | 3 | Collection CRUD in admin | Admin user, Collections |
    26→| 16 - Admin Customers | `tests/Browser/Admin/CustomerManagementTest.php` | 3 | Customer listing and detail views | Admin user, Customer user, Orders |
    27→| 17 - Admin Pages | `tests/Browser/Admin/PageManagementTest.php` | 3 | CMS page management | Admin user, Pages |
    28→| 18 - Admin Analytics | `tests/Browser/Admin/AnalyticsTest.php` | 3 | Analytics dashboard rendering | Admin user, Orders |
    29→| **Total** | **18 files** | **143** | | |
    30→
    31→---
    32→
    33→## Test Infrastructure Requirements
    34→
    35→### Framework
    36→
    37→- **Test runner:** Pest v4 with browser testing capabilities (Playwright under the hood)
    38→- **Test traits:** Each browser test file must use `TestCase` and `RefreshDatabase`
    39→- **Configuration:** Register the `Browser` test directory in `tests/Pest.php` with appropriate base classes
    40→- **Base URL:** Configured via `APP_URL` in `.env.testing`, set to `http://acme-fashion.test`
    41→
    42→### Pest v4 Browser Testing API Reference
    43→
    44→The coding agent should use these Pest v4 browser methods:
    45→
    46→| Method | Purpose |
    47→|--------|---------|
    48→| `visit(url)` | Open a real browser and navigate to the given URL |
    49→| `visit([url1, url2, ...])` | Visit multiple pages (for batch smoke testing) |
    50→| `fill(field, value)` | Type a value into a named form field |
    51→| `click(text)` | Click a visible element matching the given text |
    52→| `assertSee(text)` | Assert the page contains the given visible text |
    53→| `assertNoJavascriptErrors()` | Assert no uncaught JS exceptions occurred |
    54→| `assertNoConsoleLogs()` | Assert no console warnings or errors were logged |
    55→
    56→Additionally, standard Laravel test features are available within browser tests: factories, `Event::fake()`, `Notification::fake()`, `$this->actingAs()`, and model queries.
    57→
    58→### Environment Configuration
    59→
    60→The `.env.testing` file must contain the following keys:
    61→
    62→| Key | Value | Purpose |
    63→|-----|-------|---------|
    64→| `APP_ENV` | `testing` | Laravel environment |
    65→| `APP_URL` | `http://acme-fashion.test` | Browser base URL (served by Herd) |
    66→| `DB_CONNECTION` | `sqlite` | Database driver |
    67→| `DB_DATABASE` | Absolute path to test SQLite file | Isolated test database |
    68→| `PAYMENT_PROVIDER` | `mock` | Mock PSP - no external API keys needed |
    69→| `MAIL_MAILER` | `array` | Trap emails in memory |
    70→| `QUEUE_CONNECTION` | `sync` | Process jobs synchronously |
    71→
    72→### Prerequisites Before Running
    73→
    74→1. Database seeded with `php artisan migrate:fresh --seed`
    75→2. Laravel Herd serving `acme-fashion.test`
    76→3. Playwright browsers installed via `npx playwright install`
    77→4. Frontend assets built via `npm run build`
    78→
    79→---
    80→
    81→## Seeded Data Dependency Table
    82→
    83→All tests depend on the database seeder providing this baseline data. Each test gets a fresh database via `RefreshDatabase`, then the seeder repopulates it.
    84→
    85→Each browser test file must set `protected bool $seed = true;` on the test class (or call `$this->seed(DatabaseSeeder::class)` in `beforeEach`) to ensure the database is populated after RefreshDatabase clears it. Laravel's `RefreshDatabase` trait does NOT automatically run seeders unless explicitly configured.
    86→
    87→| Entity | Key Details | Used By Suites |
    88→|--------|-------------|----------------|
    89→| **Admin user** | Email: `admin@acme.test`, password: `password`, role: `owner` on Store 1 | 2, 3, 4, 5, 6, 12, 13, 15, 16, 17, 18 |
    90→| **Customer user** | Email: `customer@acme.test`, password: `password`, name: "John Doe", belongs to Store 1 | 10, 12 |
    91→| **Store 1** | Name: "Acme Fashion", handle: `acme-fashion`, domain: `acme-fashion.test`, currency: EUR | 1, 6, 7, 12, 14 |
    92→| **Product #1** | Title: "Classic Cotton T-Shirt", handle: `classic-cotton-t-shirt`, price: 24.99 EUR, status: active, options: Size (S/M/L/XL), Color (Black/White/Navy), inventory: in stock | 1, 3, 7, 8, 9, 11, 13, 14 |
    93→| **Product #2** | Title: "Premium Slim Fit Jeans", handle: `premium-slim-fit-jeans`, status: active, has compare-at pricing (sale), options: Size, Color | 7, 8 |
    94→| **Product #15** | Status: `draft` - must NOT appear on storefront | 3, 7 |
    95→| **Product #17** | Status: active, inventory: 0 on hand, policy: `deny` - displays "Sold out", add-to-cart disabled | 7, 11 |
    96→| **Product #18** | Status: active, inventory: 0 on hand, policy: `continue` - displays "Available on backorder", add-to-cart enabled | 7, 11 |
    97→| **Products (20 total)** | Seeded across collections, with variants, options, images, inventory | 1, 3, 7, 8, 9, 11, 13 |
    98→| **Collections** | "T-Shirts" (handle: `t-shirts`), "New Arrivals" (handle: `new-arrivals`), plus others | 1, 7, 13, 15 |
    99→| **Orders** | #1001 (status: paid, fulfillment: unfulfilled, customer: customer@acme.test), #1002, #1004 also belonging to the same customer | 4, 10, 16, 18 |
   100→| **Discounts** | WELCOME10 (10% off, min 20 EUR purchase, active), FLAT5 (5 EUR fixed, active), FREESHIP (free shipping, active), EXPIRED20 (expired end date), MAXED (usage_count >= usage_limit) | 5, 8, 9 |
   101→| **Shipping zones** | "Domestic" zone (countries: DE) with rate "Standard Shipping" at 4.99 EUR flat; "International" zone with its own rates | 6, 9 |
   102→| **Tax settings** | Store 1: manual mode, prices_include_tax varies by test | 6 |
   103→| **Pages** | "About" (handle: `about`, status: published) | 1, 7, 17 |
   104→| **Navigation** | Main menu with links to collections, about page | 7 |
   105→
   106→---
   107→
   108→## Test Execution Matrix
   109→
   110→Tests should be executed in the order shown below. Later suites depend on the infrastructure and pages verified by earlier suites.
   111→
   112→```mermaid
   113→graph TD
   114→    S1[Suite 1: Smoke Tests] --> S2[Suite 2: Admin Auth]
   115→    S1 --> S7[Suite 7: Storefront Browsing]
   116→    S2 --> S3[Suite 3: Admin Products]
   117→    S2 --> S4[Suite 4: Admin Orders]
   118→    S2 --> S5[Suite 5: Admin Discounts]
   119→    S2 --> S6[Suite 6: Admin Settings]
   120→    S2 --> S15[Suite 15: Admin Collections]
   121→    S2 --> S16[Suite 16: Admin Customers]
   122→    S2 --> S17[Suite 17: Admin Pages]
   123→    S2 --> S18[Suite 18: Admin Analytics]
   124→    S7 --> S8[Suite 8: Cart Flow]
   125→    S8 --> S9[Suite 9: Checkout Flow]
   126→    S7 --> S10[Suite 10: Customer Account]
   127→    S7 --> S11[Suite 11: Inventory Enforcement]
   128→    S7 --> S12[Suite 12: Tenant Isolation]
   129→    S7 --> S13[Suite 13: Responsive / Mobile]
   130→    S7 --> S14[Suite 14: Accessibility]
   131→```
   132→
   133→| Execution Phase | Suites | Rationale |
   134→|-----------------|--------|-----------|
   135→| Phase 1 | Suite 1 (Smoke) | Verifies all routes load before deeper testing |
   136→| Phase 2 | Suites 2, 7 | Core auth and storefront browsing - gate to all further tests |
   137→| Phase 3 | Suites 3, 4, 5, 6, 10, 11, 15, 16, 17, 18 | Admin CRUD and storefront feature suites (can run in parallel) |
   138→| Phase 4 | Suite 8 (Cart) | Depends on storefront browsing working |
   139→| Phase 5 | Suite 9 (Checkout) | Depends on cart flow working. Tests payment method selection (credit card, PayPal, bank transfer), magic card declines, and bank transfer instructions. |
   140→| Phase 6 | Suites 12, 13, 14 | Cross-cutting concerns: isolation, responsive, accessibility |
   141→
   142→---
   143→
   144→## Test Directory Structure
   145→
   146→```
   147→tests/Browser/
   148→    SmokeTest.php
   149→    Admin/
   150→        AuthenticationTest.php
   151→        ProductManagementTest.php
   152→        OrderManagementTest.php
   153→        DiscountManagementTest.php
   154→        SettingsTest.php
   155→        CollectionManagementTest.php
   156→        CustomerManagementTest.php
   157→        PageManagementTest.php
   158→        AnalyticsTest.php
   159→    Storefront/
   160→        BrowsingTest.php
   161→        CartTest.php
   162→        CheckoutTest.php
   163→        CustomerAccountTest.php
   164→        InventoryTest.php
   165→        TenantIsolationTest.php
   166→        ResponsiveTest.php
   167→        AccessibilityTest.php
   168→```
   169→
   170→---
   171→
   172→## Suite 1: Smoke Tests
   173→
   174→**File:** `tests/Browser/SmokeTest.php`
   175→
   176→**Purpose:** Hit every major public and admin page, assert they load without JavaScript errors. This is the fastest way to catch broken routes, missing views, or uncaught JS exceptions.
   177→
   178→---
   179→
   180→### Test 1.1: Loads the storefront home page
   181→
   182→**Preconditions:** Seeded store
   183→
   184→**Steps:**
   185→1. Navigate to `/`
   186→
   187→**Expected Results:**
   188→- Page displays "Acme Fashion"
   189→- No JavaScript errors
   190→
   191→---
   192→
   193→### Test 1.2: Loads a collection page
   194→
   195→**Preconditions:** Seeded collections
   196→
   197→**Steps:**
   198→1. Navigate to `/collections/t-shirts`
   199→
   200→**Expected Results:**

# 08 - Playwright E2E Test Plan

> Complete end-to-end browser test specification for the e-commerce platform using Pest v4 browser testing (Playwright-backed). All tests verify the entire application works through a real browser. This document defines requirements and specifications for the coding agent to implement.

---

## Test Suite Summary

| Suite | File | Tests | Purpose | Dependencies |
|-------|------|:-----:|---------|--------------|
| 1 - Smoke Tests | `tests/Browser/SmokeTest.php` | 10 | Hit every major page, assert HTTP 200 and no JS errors | Store 1, Products, Collections, Pages |
| 2 - Admin Authentication | `tests/Browser/Admin/AuthenticationTest.php` | 10 | Admin login, logout, invalid credentials, session access control | Admin user |
| 3 - Admin Product Management | `tests/Browser/Admin/ProductManagementTest.php` | 7 | Product CRUD: listing, creating, editing, archiving, filtering | Admin user, Products (incl. #15 draft) |
| 4 - Admin Order Management | `tests/Browser/Admin/OrderManagementTest.php` | 11 | Order listing, filtering, detail view, fulfillment, refund, confirm payment, fulfillment guard, mark shipped/delivered | Admin user, Orders (#1001, #1005), Customer |
| 5 - Admin Discount Management | `tests/Browser/Admin/DiscountManagementTest.php` | 6 | Discount code listing, creation, editing | Admin user, Discounts |
| 6 - Admin Settings | `tests/Browser/Admin/SettingsTest.php` | 7 | Store settings, shipping zones, tax config, domains | Admin user, Shipping zones, Store 1 |
| 7 - Storefront Browsing | `tests/Browser/Storefront/BrowsingTest.php` | 15 | Home page, collections, product detail, variants, search, pages | Products, Collections, Pages, Products #15/#17/#18 |
| 8 - Cart Flow | `tests/Browser/Storefront/CartTest.php` | 12 | Cart lifecycle: add, update qty, remove, discounts, totals | Products, Discounts (all codes) |
| 9 - Checkout Flow | `tests/Browser/Storefront/CheckoutTest.php` | 13 | Full checkout: contact, address, shipping, payment method selection, payment, confirmation, magic card decline, bank transfer flow | Products, Shipping zones, Discounts |
| 10 - Customer Account | `tests/Browser/Storefront/CustomerAccountTest.php` | 12 | Registration, login, order history, addresses, logout | Customer user, Orders (#1001/#1002/#1004) |
| 11 - Inventory Enforcement | `tests/Browser/Storefront/InventoryTest.php` | 4 | Inventory policy enforcement: deny vs. continue | Products #17 (deny), #18 (continue), #1 |
| 12 - Tenant Isolation | `tests/Browser/Storefront/TenantIsolationTest.php` | 5 | Multi-store data isolation verification | Store 1, Admin user, Customer user |
| 13 - Responsive / Mobile | `tests/Browser/Storefront/ResponsiveTest.php` | 8 | Mobile and tablet viewport rendering and interaction | Products, Admin user |
| 14 - Accessibility | `tests/Browser/Storefront/AccessibilityTest.php` | 11 | Heading hierarchy, ARIA labels, form labels, keyboard nav | Products, Store 1 |
| 15 - Admin Collections | `tests/Browser/Admin/CollectionManagementTest.php` | 3 | Collection CRUD in admin | Admin user, Collections |
| 16 - Admin Customers | `tests/Browser/Admin/CustomerManagementTest.php` | 3 | Customer listing and detail views | Admin user, Customer user, Orders |
| 17 - Admin Pages | `tests/Browser/Admin/PageManagementTest.php` | 3 | CMS page management | Admin user, Pages |
| 18 - Admin Analytics | `tests/Browser/Admin/AnalyticsTest.php` | 3 | Analytics dashboard rendering | Admin user, Orders |
| **Total** | **18 files** | **143** | | |

---

## Test Infrastructure Requirements

### Framework

- **Test runner:** Pest v4 with browser testing capabilities (Playwright under the hood)
- **Test traits:** Each browser test file must use `TestCase` and `RefreshDatabase`
- **Configuration:** Register the `Browser` test directory in `tests/Pest.php` with appropriate base classes
- **Base URL:** Configured via `APP_URL` in `.env.testing`, set to `http://acme-fashion.test`

### Pest v4 Browser Testing API Reference

The coding agent should use these Pest v4 browser methods:

| Method | Purpose |
|--------|---------|
| `visit(url)` | Open a real browser and navigate to the given URL |
| `visit([url1, url2, ...])` | Visit multiple pages (for batch smoke testing) |
| `fill(field, value)` | Type a value into a named form field |
| `click(text)` | Click a visible element matching the given text |
| `assertSee(text)` | Assert the page contains the given visible text |
| `assertNoJavascriptErrors()` | Assert no uncaught JS exceptions occurred |
| `assertNoConsoleLogs()` | Assert no console warnings or errors were logged |

Additionally, standard Laravel test features are available within browser tests: factories, `Event::fake()`, `Notification::fake()`, `$this->actingAs()`, and model queries.

### Environment Configuration

The `.env.testing` file must contain the following keys:

| Key | Value | Purpose |
|-----|-------|---------|
| `APP_ENV` | `testing` | Laravel environment |
| `APP_URL` | `http://acme-fashion.test` | Browser base URL (served by Herd) |
| `DB_CONNECTION` | `sqlite` | Database driver |
| `DB_DATABASE` | Absolute path to test SQLite file | Isolated test database |
| `PAYMENT_PROVIDER` | `mock` | Mock PSP - no external API keys needed |
| `MAIL_MAILER` | `array` | Trap emails in memory |
| `QUEUE_CONNECTION` | `sync` | Process jobs synchronously |

### Prerequisites Before Running

1. Database seeded with `php artisan migrate:fresh --seed`
2. Laravel Herd serving `acme-fashion.test`
3. Playwright browsers installed via `npx playwright install`
4. Frontend assets built via `npm run build`

---

## Seeded Data Dependency Table

All tests depend on the database seeder providing this baseline data. Each test gets a fresh database via `RefreshDatabase`, then the seeder repopulates it.

Each browser test file must set `protected bool $seed = true;` on the test class (or call `$this->seed(DatabaseSeeder::class)` in `beforeEach`) to ensure the database is populated after RefreshDatabase clears it. Laravel's `RefreshDatabase` trait does NOT automatically run seeders unless explicitly configured.

| Entity | Key Details | Used By Suites |
|--------|-------------|----------------|
| **Admin user** | Email: `admin@acme.test`, password: `password`, role: `owner` on Store 1 | 2, 3, 4, 5, 6, 12, 13, 15, 16, 17, 18 |
| **Customer user** | Email: `customer@acme.test`, password: `password`, name: "John Doe", belongs to Store 1 | 10, 12 |
| **Store 1** | Name: "Acme Fashion", handle: `acme-fashion`, domain: `acme-fashion.test`, currency: EUR | 1, 6, 7, 12, 14 |
| **Product #1** | Title: "Classic Cotton T-Shirt", handle: `classic-cotton-t-shirt`, price: 24.99 EUR, status: active, options: Size (S/M/L/XL), Color (Black/White/Navy), inventory: in stock | 1, 3, 7, 8, 9, 11, 13, 14 |
| **Product #2** | Title: "Premium Slim Fit Jeans", handle: `premium-slim-fit-jeans`, status: active, has compare-at pricing (sale), options: Size, Color | 7, 8 |
| **Product #15** | Status: `draft` - must NOT appear on storefront | 3, 7 |
| **Product #17** | Status: active, inventory: 0 on hand, policy: `deny` - displays "Sold out", add-to-cart disabled | 7, 11 |
| **Product #18** | Status: active, inventory: 0 on hand, policy: `continue` - displays "Available on backorder", add-to-cart enabled | 7, 11 |
| **Products (20 total)** | Seeded across collections, with variants, options, images, inventory | 1, 3, 7, 8, 9, 11, 13 |
| **Collections** | "T-Shirts" (handle: `t-shirts`), "New Arrivals" (handle: `new-arrivals`), plus others | 1, 7, 13, 15 |
| **Orders** | #1001 (status: paid, fulfillment: unfulfilled, customer: customer@acme.test), #1002, #1004 also belonging to the same customer | 4, 10, 16, 18 |
| **Discounts** | WELCOME10 (10% off, min 20 EUR purchase, active), FLAT5 (5 EUR fixed, active), FREESHIP (free shipping, active), EXPIRED20 (expired end date), MAXED (usage_count >= usage_limit) | 5, 8, 9 |
| **Shipping zones** | "Domestic" zone (countries: DE) with rate "Standard Shipping" at 4.99 EUR flat; "International" zone with its own rates | 6, 9 |
| **Tax settings** | Store 1: manual mode, prices_include_tax varies by test | 6 |
| **Pages** | "About" (handle: `about`, status: published) | 1, 7, 17 |
| **Navigation** | Main menu with links to collections, about page | 7 |

---

## Test Execution Matrix

Tests should be executed in the order shown below. Later suites depend on the infrastructure and pages verified by earlier suites.

```mermaid
graph TD
    S1[Suite 1: Smoke Tests] --> S2[Suite 2: Admin Auth]
    S1 --> S7[Suite 7: Storefront Browsing]
    S2 --> S3[Suite 3: Admin Products]
    S2 --> S4[Suite 4: Admin Orders]
    S2 --> S5[Suite 5: Admin Discounts]
    S2 --> S6[Suite 6: Admin Settings]
    S2 --> S15[Suite 15: Admin Collections]
    S2 --> S16[Suite 16: Admin Customers]
    S2 --> S17[Suite 17: Admin Pages]
    S2 --> S18[Suite 18: Admin Analytics]
    S7 --> S8[Suite 8: Cart Flow]
    S8 --> S9[Suite 9: Checkout Flow]
    S7 --> S10[Suite 10: Customer Account]
    S7 --> S11[Suite 11: Inventory Enforcement]
    S7 --> S12[Suite 12: Tenant Isolation]
    S7 --> S13[Suite 13: Responsive / Mobile]
    S7 --> S14[Suite 14: Accessibility]
```

| Execution Phase | Suites | Rationale |
|-----------------|--------|-----------|
| Phase 1 | Suite 1 (Smoke) | Verifies all routes load before deeper testing |
| Phase 2 | Suites 2, 7 | Core auth and storefront browsing - gate to all further tests |
| Phase 3 | Suites 3, 4, 5, 6, 10, 11, 15, 16, 17, 18 | Admin CRUD and storefront feature suites (can run in parallel) |
| Phase 4 | Suite 8 (Cart) | Depends on storefront browsing working |
| Phase 5 | Suite 9 (Checkout) | Depends on cart flow working. Tests payment method selection (credit card, PayPal, bank transfer), magic card declines, and bank transfer instructions. |
| Phase 6 | Suites 12, 13, 14 | Cross-cutting concerns: isolation, responsive, accessibility |

---

## Test Directory Structure

```
tests/Browser/
    SmokeTest.php
    Admin/
        AuthenticationTest.php
        ProductManagementTest.php
        OrderManagementTest.php
        DiscountManagementTest.php
        SettingsTest.php
        CollectionManagementTest.php
        CustomerManagementTest.php
        PageManagementTest.php
        AnalyticsTest.php
    Storefront/
        BrowsingTest.php
        CartTest.php
        CheckoutTest.php
        CustomerAccountTest.php
        InventoryTest.php
        TenantIsolationTest.php
        ResponsiveTest.php
        AccessibilityTest.php
```

---

## Suite 1: Smoke Tests

**File:** `tests/Browser/SmokeTest.php`

**Purpose:** Hit every major public and admin page, assert they load without JavaScript errors. This is the fastest way to catch broken routes, missing views, or uncaught JS exceptions.

---

### Test 1.1: Loads the storefront home page

**Preconditions:** Seeded store

**Steps:**
1. Navigate to `/`

**Expected Results:**
- Page displays "Acme Fashion"
- No JavaScript errors

---

### Test 1.2: Loads a collection page

**Preconditions:** Seeded collections

**Steps:**
1. Navigate to `/collections/t-shirts`

**Expected Results:**