Skip to main content

PRD Template

Copy into docs/prds/<slug>-<cu-id>.md and fill in. The PRD is the single source of truth for what a feature is and why we're building it. It's owned by Product. R&D translates it into a Design Doc before any code lands.

The PRD's UI section names the design-system components from @bewith-dev/design-system's COMPONENTS.md catalog. Without this anchoring, Claude Code reinvents components.


What lives here (and what doesn't)โ€‹

The PRD is WHAT and WHY:

  • Problem, users, scope, requirements, flows
  • Exact product copy (text + RTL)
  • UI Composition โ€” naming existing design-system components
  • Constraints โ€” analytics events to fire, permissions, performance targets, accessibility
  • Acceptance criteria

The PRD is NOT HOW:

  • โŒ API endpoints, methods, schemas
  • โŒ Database tables, fields, indexes
  • โŒ Architecture, services, queues, caching
  • โŒ Library / framework choices
  • โŒ Implementation algorithms

If you find yourself writing any of the above, move it to the Design Doc and replace it here with the requirement ("the system must remember which categories a resident subscribed to and when") โ€” not the implementation.


---
id: prd-<slug>
title: "PRD: <Feature Name>"
description: "<one-sentence summary that shows in the index>"

# Lifecycle โ€” see /methodology/product-rd-handoff for the full status table
status: draft # draft | ready-for-rd | in-progress | shipped | deprecated
author: "@<your-handle>"
created: <YYYY-MM-DD>
updated: <YYYY-MM-DD>

# ClickUp parent task (required when status >= ready-for-rd)
clickup_parent: "CU-XXXXX"
clickup_url: "https://app.clickup.com/t/XXXXX"

# Which BeWith repos this feature touches
affected_repos: [backend, organization-dashboard, consumer, iframes, facilities]

# Design reference โ€” Figma frame URL OR Claude Design code branch URL
design_reference: "https://www.figma.com/file/.../?node-id=..."

# Cross-links โ€” fill in once they exist
related_design_doc: null # docs/designs/<slug>-<cu-id>.md
related_prds: [] # peer PRDs

ai_assisted: false # set true if AI generated the first draft
tags: []
---

# PRD: <Feature Name>

<div style={{display:'flex',gap:'0.5rem',marginBottom:'1.5rem'}}>
<span className="badge badge--primary">Draft</span>
<span className="badge badge--secondary">Author: @handle</span>
<span className="badge badge--secondary">CU-XXXXX</span>
</div>

## TL;DR

Three to five sentences: **what we're building, for whom, and why now**. A reader should be able to skim this and know whether to keep reading.

---

## Definition of Ready (gate โ€” do not move to `ready-for-rd` until all checked)

This is the contract that prevents "we started and immediately got blocked."

- [ ] Problem and goal are clear and agreed.
- [ ] Success metrics are measurable.
- [ ] Scope (in / out / deferred) is explicit.
- [ ] Every **P0** functional requirement is fully specified โ€” no P0 depends on an unresolved Open Question.
- [ ] **No P0-blocking Open Questions remain** (ยง10). Non-blocking ones may stay, with an owner.
- [ ] UI is provided for **every P0 screen and every state** (default / loading / empty / error / success / disabled) โ€” see ยง7.
- [ ] Exact copy is provided as **text** (not only inside images), including RTL/Hebrew strings.
- [ ] Acceptance criteria are testable (ยง9).
- [ ] Constraints stated: permissions, feature flag, analytics events, performance, accessibility (ยง8).

---

## 1. Problem & Context

The user pain, the situation today, and the "why now". Describe the problem, **not the solution**. Cite the signal (data, incident, customer quote) where possible.

## 2. Goals & Success Metrics

- **Goal:** <one or two sentences โ€” the outcome we want>
- **Metric 1:** <measurable, with target + timeframe โ€” e.g. "โ‰ฅ50% of active residents subscribe to โ‰ฅ1 category within 60 days">
- **Metric 2:** <โ€ฆ>
- **Non-goal:** <what success is explicitly NOT โ€” prevents scope creep>

## 3. Scope

**In scope**

- <capability>

**Out of scope**

- <capability>

**Deferred to vNext**

- <capability โ€” name the version if known>

## 4. User Stories

Format: `As a <role>, I want <capability> so that <value>.` Include a `system` actor for automated behavior.

- As a <role>, I want <โ€ฆ> so that <โ€ฆ>.

## 5. Functional Requirements

Describe **behavior and outcome**, not implementation. `MUST` = required (P0); `SHOULD` = preferred (P1/P2). Keep priority consistent โ€” a `MUST` is P0, a `SHOULD` is P1/P2. Reference the UI screen each requirement maps to.

| # | Requirement (behavior / outcome) | Priority | UI ref (ยง7) |
|---|---|---|---|
| FR-01 | The system MUST <โ€ฆ> | P0 | <screen name> |
| FR-02 | The system SHOULD <โ€ฆ> | P1 | <screen name> |

## 6. User Flows & States

### Happy path โ€” <flow name>

1. <step>
2. <step>

### Edge cases & error states

| Scenario | Expected behavior |
|---|---|
| <e.g. duplicate name> | <inline validation, message text, modal stays open> |
| <API failure> | <error toast text, form data preserved> |
| <empty state> | <what the user sees> |

## 7. UI & Design Handoff

### 7.1 Design Reference

- **Source of truth:** <Figma Dev Mode link OR Claude Design code branch URL>
- **For Claude Code specifically:** a **self-contained HTML/React prototype is best** โ€” the agent reads markup, class names, copy, and states directly. A Figma *editor* link is not machine-readable; if using Figma, ensure the link is to a **Dev Mode** frame, and confirm Dev Mode MCP is configured (see [`docs/methodology/product-rd-handoff`](/methodology/product-rd-handoff)).

### 7.2 UI Composition โ€” the deterministic core

For each screen / area, name the **existing** design-system components and tokens. Check [`@bewith-dev/design-system`'s `COMPONENTS.md`](https://github.com/bewith-dev/design-system) for exact names. This is what stops Claude from rebuilding a `<Button>` or inventing a color.

| Screen / area | Components (from `COMPONENTS.md`) | Tokens (`palette.ts` / theme) | Notes |
|---|---|---|---|
| <e.g. Header> | `SummaryCard`, `Chip`, `Button` | `semantic.success`, `spacing(2)` | primary action right-aligned |

**New or changed components/tokens?** Do not bury them in prose here. Itemize each one in **ยง7.2.a Design-system deltas** below, with its delta type. That table is what turns each into a design-system task. **Never plan a one-off in the consuming app.**

### 7.2.a Design-system deltas

Every design-system change this feature implies, itemized so the handoff can turn each one into a task. This table is the **deterministic input** to [`/plan-feature`](/commands/plan-feature): it reads the rows top-down and emits one design-system task per non-`reuse` row, recorded in the Design Doc as a prerequisite that ships **before** the feature is built in the consuming app.

List **`reuse`** rows too (their DS task is `none`), so ยง7.2.a is the complete account of what each named component needs: what already exists and what must be built. Only non-`reuse` rows become tasks.

| Target (component / region) | Delta type | Description (what / why, + token if relevant) | DS task |
|---|---|---|---|
| `SummaryCard` | reuse | balance header, used as-is | none |
| `SummaryCard` | variant | add an `accent` style for the available-balance state; uses `semantic.success` | `/add-variant SummaryCard accent` |
| `AmountStepper` | element | new numeric-stepper primitive for the amount field | `/add-component AmountStepper element` |
| `WithdrawalWizard` | component | new multi-step composed component for the flow | `/add-component WithdrawalWizard component` |
| `WithdrawalRow` | composite | row assembled only from `Avatar` + `Chip` + `Text`, no new primitive | `/add-composite WithdrawalRow ...` |

**Delta type uses the catalog's own vocabulary** (the [`COMPONENTS.md`](https://github.com/bewith-dev/design-system) sections + the design-system commands), so each value maps 1:1 to a command:

| Delta type | Meaning | DS task |
|---|---|---|
| `reuse` | already in `COMPONENTS.md` โ€” use as-is | none (note the import path in ยง7.2) |
| `variant` | extend an existing catalog component with a new prop / state / style; never fork | `/add-variant <Component> <desc>` |
| `element` | a brand-new primitive | `/add-component <Name> element` |
| `component` | a brand-new composed / feature-level component | `/add-component <Name> component` |
| `composite` | a new component assembled **only** from existing catalog pieces (no new primitive) | `/add-composite <Name> <desc>` |

These commands run in [`@bewith-dev/design-system`](https://github.com/bewith-dev/design-system), not the consuming app. A delta is a change to the shared system, never a local one-off.

### 7.3 States to implement (per screen)

Provide the prototype for ALL of these โ€” missing states are the #1 cause of rework.

- Default / idle
- Loading / skeleton
- Empty
- Error (with exact message text)
- Success (toast / confirmation text)
- Disabled (when, and why)
- Selected / active (filters, chips, etc.)

### 7.4 Copy โ€” exact, as text

| Element | Text (RTL/Hebrew where relevant) |
|---|---|
| <Page title> | "<โ€ฆ>" |
| <Create button> | "<โ€ฆ>" |
| <Error toast> | "<โ€ฆ>" |

**No em-dashes (โ€”) in customer-facing copy.** Em-dashes are an AI tell; user-facing copy must read as human. Use periods, commas, colons, parentheses, or hyphens for compound words only. See [`feedback_em_dash_scope`](https://github.com/bewith-dev/bewith-docs/blob/master/memory/feedback_em_dash_scope.md). PRD prose itself is exempt โ€” em-dashes are fine in section narrative.

### 7.5 Design System Authority

- **Pixel-perfect is not required; behavior and states are.** The Design Reference is authoritative for layout, copy, and states. Styling uses existing `@bewith-dev/design-system` components.
- **Direction & locale:** <e.g. "Dashboard is RTL Hebrew; Consumer is bilingual">.
- **Responsive:** <what changes between mobile and desktop>.

## 8. Constraints & Non-Functional Requirements

These are legitimate **product/business** inputs โ€” the WHAT. They are NOT the technical solution. Say "must integrate with the existing notifications system" โ€” not which API or table.

- **Permissions / roles:** <who can do what>
- **Feature flag:** <flag name, default state, who flips it>
- **Performance (user-visible):** <e.g. "bulk action on 50 items completes < 5s; show progress > 3s">
- **Accessibility:** <keyboard nav, screen-reader labels, focus order>
- **Localization / direction:** <RTL, languages>
- **Depends on existing systems:** <e.g. events system, push/notifications, hubs>

### 8.1 Analytics events (Law 2 โ€” Observability)

The events the platform must fire, with their business meaning. R&D names the technical payload in the Design Doc; here we name **what to measure and why**.

| Event (business name) | When it fires | Why we measure it | Measured dimension |
|---|---|---|---|
| `event_registered` | User completes registration | Adoption + pricing | `users`, `calls` |
| `event_cancelled` | User cancels reg | Drop-off analysis | `users` |

### 8.2 API-accessible capabilities (Law 1 โ€” API-First)

Business-logic actions that must be programmatically accessible (not UI-only). R&D designs the endpoints in the Design Doc; here we name **what must be reachable**.

| Capability | Why it needs API access |
|---|---|
| <e.g. Register for event> | <e.g. 3rd-party integrations and analytics dashboards> |

### 8.3 Activation config (Law 3 โ€” Self-Serve Activation)

The questions the central activation agent will ask the customer to enable this feature. Defaults and business rules โ€” the implementation of the activation agent lives elsewhere (a platform-wide initiative).

| Question | Type | Default | Required? | Business rule |
|---|---|---|---|---|
| <e.g. "Enable SMS reminders?"> | yes/no | yes | yes | none |
| <e.g. "Hours before event?"> | number 1-72 | 24 | yes | reasonable bounds |

Skip ยง8.3 if the feature has no activation surface (purely internal, no customer-facing toggle).

## 9. Acceptance Criteria

Given / When / Then, testable, each mapped to FRs. This is the contract QA and the agent's tests verify against.

- Given <context>, when <action>, then <observable result>. *(FR-01)*
- Given <context>, when <action>, then <observable result>. *(FR-13)*
- All dashboard UI renders correctly in RTL.
- Analytics events from ยง8.1 fire for all tracked actions.
- Feature is gated behind the feature flag from ยง8.

## 10. Open Questions

Mark whether each blocks a P0. **The PRD cannot reach `ready-for-rd` while any "Blocks P0?" = Yes.**

| # | Question | Owner | Blocks P0? | Resolution |
|---|---|---|---|---|
| 1 | <โ€ฆ> | <PM> | Yes / No | <fill when resolved> |

## 11. Out of Scope / Future

- **vNext:** <capability>
- <capability>

---

## What does NOT belong in this document

These belong in the [Design Doc](/templates/design-doc):

- API endpoint design โ€” request/response contracts
- Database schema โ€” table & field names
- Architecture โ€” services, queues, caching
- Library / framework choices
- Implementation algorithms

If you find yourself writing any of the above, move it to the Design Doc and replace it here with the *requirement* (e.g. "the system must remember which categories a resident subscribed to and when").