Files
agentic-dev-template/docs/guides/frontend-work-shape.md
Danijel Martinek 9576987637 docs(architecture): agent-first workflow design + work-shape guides
Captures the design from the brainstorm session on agent-first development
in this template. Architecture doc covers the four interlocking pillars:

- Conformance engine (manifest + brands + ESLint + boot + CI gate)
- Agent workflow (PRD -> Epic -> Story -> Task; manifest-first ordering;
  TDD per slice; in/out scope at every level)
- Local task system at docs/work/ (filesystem markdown, derived committed
  _state.json, single-writer orchestrator rule)
- Sandcastle orchestrator (implementer + reviewer loop, DAG-respecting,
  configurable retry cap)

Work-shape guides extend the architecture doc with operational detail for
frontend work (atomic design, Storybook-as-spec, component + Playwright
screenshot test gates, Storybook MCP reviewer integration) and
infrastructure work (ADR-first flow, dedicated ADR elicitation skill,
optional core packages vs. new infrastructure layers).

Phasing is conformance-first: build the enforcement system manually, then
build the dispatch substrate, then migrate remaining features through it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:08:44 +02:00

130 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Frontend work shape
How frontend work — components, pages, media UI, anything visual — flows through the agent-first workflow. For the broader workflow context see [`docs/architecture/agent-first-workflow-and-conformance.md`](../architecture/agent-first-workflow-and-conformance.md).
## When this guide applies
You're working on:
- A new or existing component (atom / molecule / organism / template / page)
- A page in `apps/web-next` or `apps/web-tanstack`
- A visual or interactive change in `@repo/core-ui` or `features/<feature>/src/ui/`
- Storybook stories or visual regression tests
If you're working on a backend use case (factory, repository, manifest entry, event handler, job, realtime channel), use the default backend shape documented in the architecture doc — not this guide.
## Where frontend code lives
| Surface | Location | When to use |
|---|---|---|
| Atomic-design primitives | `@repo/core-ui/src/{atoms,molecules,organisms,templates}/` | Cross-feature reusables. Generated via `pnpm turbo gen core-ui-component`. |
| Feature-scoped UI | `features/<feature>/src/ui/` | Components and queries specific to a feature. Exported behind the feature's `./ui` subpath, never the root barrel (see CLAUDE.md). |
| Pages | `apps/<app>/src/...` (Next.js: `app/`, TanStack: `routes/`) | Page-level composition. Calls use cases via tRPC controllers; composes components. |
## Atomic design conventions
Tier rules (enforced by the `atomic-tier-import-direction` ESLint rule):
| Tier | May import from | May NOT import from |
|---|---|---|
| `atoms` | nothing else in `core-ui` | molecules / organisms / templates / pages / features |
| `molecules` | atoms | organisms / templates / pages / features |
| `organisms` | atoms, molecules | templates / pages / features |
| `templates` | atoms, molecules, organisms | pages / features |
| `pages` | all of the above | other pages |
Feature-scoped UI (`features/<feature>/src/ui/`) follows the same tier order internally, and may import from `@repo/core-ui` at any tier.
## Storybook is the spec
Every component has a sibling `.stories.tsx`. The story file:
- Declares one story per AC bullet (or one variant per AC bullet)
- Uses Storybook's `play` function for interaction tests where applicable
- Becomes the shared visual contract between human, implementer agent, reviewer agent
**Acceptance criteria for a frontend task map directly to story variants:**
```markdown
## Acceptance criteria
- [ ] Renders default variant
- [ ] Renders loading state
- [ ] Renders error state with `message` slot
- [ ] Renders disabled state
- [ ] Click handler fires with event payload
```
Each bullet becomes one `Story` export (or one `play` step on a story).
## Test gates
| Gate | What it covers | Tool | Latency | When it runs |
|---|---|---|---|---|
| Component test | behavior, props, interactions | Vitest + Testing Library, or `play` on stories | <5s | pre-commit, CI |
| Visual regression | rendered appearance vs. baseline | Playwright screenshot tests | 30120s | CI only; blocks merge on unapproved diffs |
The visual regression infrastructure ships as part of the `work-system-v1` epic. Until it's in place, frontend work relies on component tests + manual visual review.
## Adapted four-step ordering
For a pure UI slice (no backend coupling):
1. **Story file** write or extend `.stories.tsx`; declare the variant for this slice's AC bullet. *This is the visual spec — analogous to the manifest entry for backend work.*
2. **Contracts** props interface in the component file (factory body / render body may still throw `not implemented`)
3. **Tests (red)** component test + the new story (the rendered output is asserted as part of the visual regression baseline, or via Testing Library)
4. **Implementation (green)** render JSX, wire interactions, satisfy AC
For a UI slice that consumes a backend use case (e.g. a form component calling `auth.signUp`), the use case lives in a separate story with its own four steps; the UI story `depends-on` the use-case story.
## Reviewer integration
The reviewer agent for frontend tasks uses two extra inputs beyond the standard diff:
1. **Storybook MCP** at `http://localhost:6006/mcp` query existing components, list variants, fetch the metadata for stories that already exist. The reviewer can `list-all-documentation` to verify no duplicate component was created.
2. **Playwright screenshot CI verdict** the visual diff status from CI. Unapproved diffs trigger `reject` regardless of code quality.
Reviewer checklist for frontend tasks:
- [ ] Every AC bullet has a matching story or `play` step
- [ ] No accidental cross-tier imports (lint already catches this, but verify)
- [ ] Component test exercises each AC bullet
- [ ] Visual regression diff is either zero or human-approved
- [ ] No new component created without checking for an existing equivalent via Storybook MCP
## Story split for page-level features
A user-facing feature like "sign up" decomposes into multiple stories under one epic:
```
Epic: auth-v1
├── Story (user-story): auth.signUp use case
├── Story (technical-story): SignUpForm component
│ depends-on: signUp use case
└── Story (technical-story): /sign-up page
depends-on: SignUpForm
```
Each story has its own AC checklist; the `depends-on` edges enforce sequential dispatch by the orchestrator. The page story typically includes the Playwright E2E test for the full flow.
## Conformance for frontend
New ESLint rules added under the frontend work-shape:
- `component-must-have-story` every `.tsx` file exporting a default OR named React component must have a sibling `.stories.tsx`
- `component-must-have-test` every component must have a sibling `.test.tsx` (or be covered by a `play` function on its story)
- `atomic-tier-import-direction` tier imports must respect the table above
- `story-must-cover-all-prop-variants` (advisory) discriminated-union props should have a story per variant
## Common pitfalls
- **Stale stories.** A component changes prop shape; stories don't get updated. The `component-must-have-story` rule catches missing stories but not stale ones. Reviewer should flag this; visual regression catches the rendered consequence.
- **Visual-only changes without story update.** A CSS tweak that doesn't change behavior still needs the story to be re-snapshotted. Treat the visual regression diff approval as part of the slice.
- **Cross-tier creep.** Tempting to import an organism from inside an atom for "convenience". The lint rule blocks it; refactor the shared bit down to an atom or molecule.
- **Duplicate components.** An agent creates a `Button` in a feature's `ui/atoms/` when one already exists in `core-ui`. Reviewer queries Storybook MCP for `Button` before approval; if duplicated, rejects.
## Open items (filled in as we ship)
- Playwright screenshot infrastructure exact setup, baseline storage, approval flow
- Visual regression PR check GitHub workflow + diff hosting
- Storybook test integration (`test:stories`) current status and what we extend