Skip to main content
The /sample-data command creates or updates sample data for a section. Sample data populates screen designs with realistic content and generates TypeScript types for components.

Prerequisites

Before generating sample data:
  • Section spec must exist at product/sections/[section-id]/spec.md
  • Run /shape-section first if not created
Sample data is automatically generated during /shape-section. Use /sample-data to modify the data structure or sample records after creation.

When to Use This Command

Run /sample-data when you need to:
  • Add new fields to entities
  • Change data structure
  • Update sample records
  • Add more sample records
  • Adjust entity relationships
  • Regenerate types after data changes

Sample Data Structure

Sample data consists of two parts:

1. Metadata (_meta)

Human-readable descriptions of entities and relationships:
{
  "_meta": {
    "models": {
      "invoices": "Each invoice represents a bill you send to a client for work completed.",
      "lineItems": "Line items are the individual services or products listed on each invoice."
    },
    "relationships": [
      "Each Invoice contains one or more Line Items (the breakdown of charges)",
      "Invoices track which Client they belong to via the clientName field"
    ]
  }
}
```plaintext

**Purpose:**
- Displayed in Design OS interface
- Explains entities in plain language
- Describes conceptual relationships (not database relationships)
- Helps maintain consistency across sections

### 2. Sample Records

Realistic data for screen designs:

```json
{
  "invoices": [
    {
      "id": "inv-001",
      "invoiceNumber": "INV-2024-001",
      "clientName": "Acme Corp",
      "clientEmail": "[email protected]",
      "total": 1500.00,
      "status": "sent",
      "dueDate": "2024-02-15",
      "lineItems": [
        {
          "description": "Web Design",
          "quantity": 1,
          "rate": 1500.00
        },
        {
          "description": "Logo Design",
          "quantity": 2,
          "rate": 500.00
        }
      ]
    },
    {
      "id": "inv-002",
      "invoiceNumber": "INV-2024-002",
      "clientName": "TechStart Inc",
      "clientEmail": "[email protected]",
      "total": 3200.00,
      "status": "paid",
      "dueDate": "2024-02-20",
      "lineItems": []
    }
  ]
}
```plaintext

**Characteristics:**
- 5-10 realistic records (enough for a list view)
- Varied content (short/long text, different statuses)
- Edge cases (empty arrays, long descriptions, null values)
- Believable names and data (not "Lorem ipsum" or "Test 123")
- TypeScript-friendly field names (camelCase)

## The Sample Data Process

<Steps>

### Select a Section

Choose which section to generate or update data for. Single sections are auto-selected.

### Handle Existing Data

**If data already exists:**

You'll be asked:
```plaintext
Sample data already exists for Invoice Management. What would you like
to change about the existing data shape or sample data?
```plaintext

Describe your requested changes, and the AI immediately updates `data.json` and `types.ts`.

**If no data exists:**

The AI proceeds to generate new data from the spec.

### Check Global Data Shape

If a global data shape exists at `product/data-shape/data-shape.md`, the AI:
- Uses entity names from the global shape
- Follows described relationships
- Maintains consistent vocabulary

<Note>
If no global data shape exists, a warning appears but generation continues.
</Note>

### Analyze Spec Requirements

The AI reads the spec to determine:
- What entities are needed
- What fields each entity requires
- What actions can be taken (become callback props)
- What sample values would be realistic

### Generate Files

Two files are created automatically:

**1. data.json** - Sample data with metadata

**2. types.ts** - TypeScript interfaces

</Steps>

## TypeScript Type Generation

Types are inferred from sample data and spec requirements:

```typescript
// =============================================================================
// UI Data Shapes — These define the data the components expect to receive
// =============================================================================

export interface LineItem {
  description: string
  quantity: number
  rate: number
}

export interface Invoice {
  id: string
  invoiceNumber: string
  clientName: string
  clientEmail: string
  total: number
  status: 'draft' | 'sent' | 'paid' | 'overdue'
  dueDate: string
  lineItems: LineItem[]
}

// =============================================================================
// Component Props
// =============================================================================

export interface InvoiceListProps {
  /** The list of invoices to display */
  invoices: Invoice[]
  /** Called when user wants to view an invoice's details */
  onView?: (id: string) => void
  /** Called when user wants to edit an invoice */
  onEdit?: (id: string) => void
  /** Called when user wants to delete an invoice */
  onDelete?: (id: string) => void
  /** Called when user wants to create a new invoice */
  onCreate?: () => void
}
```plaintext

### Type Inference Rules

| Sample Data | TypeScript Type |
|------------|------------------|
| `"text"` | `string` |
| `42` | `number` |
| `true` | `boolean` |
| `[...]` | `TypeName[]` |
| `{...}` | Named interface |
| `"draft"`, `"sent"`, etc. | `'draft' \| 'sent' \| 'paid' \| 'overdue'` (union type) |

### Props Interface

The Props interface includes:

**Data props:**
```typescript
invoices: Invoice[]  // Main data from data.json
```plaintext

**Callback props:**
```typescript
onView?: (id: string) => void      // Optional, from spec actions
onEdit?: (id: string) => void      // JSDoc explains when called
onDelete?: (id: string) => void
onCreate?: () => void
```plaintext

### Naming Conventions

- **Interfaces**: PascalCase (`Invoice`, `LineItem`, `InvoiceListProps`)
- **Properties**: camelCase (`clientName`, `dueDate`, `lineItems`)
- **Props interface**: `[SectionName]Props` (e.g., `InvoiceListProps`)
- **Callbacks**: Optional with JSDoc comments

## Sample Data Best Practices

### Use Realistic Content

**Good:**
```json
{
  "clientName": "Acme Corporation",
  "description": "Brand identity design including logo, color palette, and style guide"
}
```plaintext

**Bad:**
```json
{
  "clientName": "Test Client 1",
  "description": "Lorem ipsum dolor sit amet"
}
```plaintext

### Include Variety

**Mix content lengths:**
```json
[
  { "description": "Logo design" },
  { "description": "Complete brand identity package including logo, business cards, letterhead, and brand guidelines document" }
]
```plaintext

**Mix statuses:**
```json
[
  { "status": "draft" },
  { "status": "sent" },
  { "status": "paid" },
  { "status": "overdue" }
]
```plaintext

### Add Edge Cases

**Empty arrays:**
```json
{
  "id": "inv-002",
  "lineItems": []  // Shows how UI handles empty state
}
```plaintext

**Long text:**
```json
{
  "notes": "This is a very long note that demonstrates how the UI handles extended content. It should wrap properly and not break the layout even when containing multiple sentences and paragraphs of text."
}
```plaintext

**Boundary values:**
```json
[
  { "total": 0.00 },      // Zero amount
  { "total": 999999.99 }  // Large amount
]
```plaintext

## Global Data Shape Integration

When a global data shape exists:

**Entity names match:**
```json
// Global data shape defines "invoices"
// Sample data uses "invoices" (not "invoice_list")
{
  "_meta": {
    "models": {
      "invoices": "..."
    }
  },
  "invoices": [...]
}
```plaintext

**Relationships align:**
```json
// If global shape says "invoices have clients"
{
  "_meta": {
    "relationships": [
      "Each Invoice belongs to a Client via clientId"
    ]
  }
}
```plaintext

This ensures consistency when multiple sections share entities.

## File Output Locations

```plaintext
product/sections/[section-id]/
├── data.json        # Sample data with _meta
└── types.ts         # TypeScript interfaces
```plaintext

## After Generation

The AI confirms:

```plaintext
I've created two files for Invoice Management:

1. product/sections/invoice-management/data.json - Sample data with 5 records

2. product/sections/invoice-management/types.ts - TypeScript interfaces

The types include:
- Invoice - The main data type
- InvoiceListProps - Props interface for the component (includes callbacks for view, edit, delete, create)

Review the files and let me know if you'd like any adjustments.
When you're ready, run /design-screen to create the screen design.
```plaintext

## Next Steps

1. **Review the files** - Check that data structure matches your needs
2. **Request changes** - Describe any adjustments needed
3. **Design screens** - Run `/design-screen` when ready

## Updating Sample Data

To modify existing data:

```plaintext
/sample-data
```plaintext

Describe your changes:
- "Add a `priority` field to tasks"
- "Include 3 more sample records"
- "Change the status values to include 'archived'"
- "Add nested `attachments` array to each item"

Both `data.json` and `types.ts` are updated automatically.

Build docs developers (and LLMs) love