Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/snarktank/ralph/llms.txt

Use this file to discover all available pages before exploring further.

Notification System Example

This example shows how to break a complex feature (a notification system) into small, focused stories that Ralph can execute autonomously. The key challenge is splitting work into stories completable in one context window.

The Challenge

Original requirement: “Add user notifications to the app” This is far too big for one story. Let’s break it down properly.

Story Breakdown Strategy

1

Identify Layers

Split by technical layer:
  • Data layer: Database schema
  • Logic layer: Services and actions
  • UI layer: Components and pages
  • Integration: Connecting the pieces
2

Order by Dependencies

Later stories depend on earlier ones:
  1. Schema (nothing works without this)
  2. Write operations (creating notifications)
  3. Read operations (fetching notifications)
  4. Display (showing notifications)
  5. Interactions (marking as read, etc.)
3

Keep Stories Small

Each story should be:
  • Completable in 1 context window
  • Describable in 2-3 sentences
  • Independently testable

Complete prd.json

{
  "project": "MyApp",
  "branchName": "ralph/notification-system",
  "description": "Notification System - Add in-app notifications for user actions",
  "userStories": [
    {
      "id": "US-001",
      "title": "Add notifications table to database",
      "description": "As a developer, I need to store notifications so users can view them later.",
      "acceptanceCriteria": [
        "Add notifications table with columns: id, userId, type, message, read (boolean), createdAt",
        "Add index on userId for fast queries",
        "Generate and run migration successfully",
        "Typecheck passes"
      ],
      "priority": 1,
      "passes": false,
      "notes": ""
    },
    {
      "id": "US-002",
      "title": "Create notification service for sending notifications",
      "description": "As a developer, I need a service to create notifications when events occur.",
      "acceptanceCriteria": [
        "Create NotificationService.create(userId, type, message) function",
        "Insert notification into database",
        "Return created notification object",
        "Add unit tests for service",
        "Typecheck passes"
      ],
      "priority": 2,
      "passes": false,
      "notes": ""
    },
    {
      "id": "US-003",
      "title": "Add notification bell icon to header",
      "description": "As a user, I want to see when I have new notifications.",
      "acceptanceCriteria": [
        "Add bell icon to top navigation bar",
        "Show unread count badge when notifications exist",
        "Badge displays number of unread notifications",
        "Typecheck passes",
        "Verify in browser using dev-browser skill"
      ],
      "priority": 3,
      "passes": false,
      "notes": ""
    },
    {
      "id": "US-004",
      "title": "Create notification dropdown panel",
      "description": "As a user, I want to view my notifications in a dropdown.",
      "acceptanceCriteria": [
        "Clicking bell icon opens dropdown panel",
        "Panel shows list of recent notifications (max 10)",
        "Each notification shows message, type icon, and timestamp",
        "Unread notifications have colored background",
        "Clicking outside closes panel",
        "Typecheck passes",
        "Verify in browser using dev-browser skill"
      ],
      "priority": 4,
      "passes": false,
      "notes": ""
    },
    {
      "id": "US-005",
      "title": "Add mark-as-read functionality",
      "description": "As a user, I want to mark notifications as read.",
      "acceptanceCriteria": [
        "Clicking a notification marks it as read",
        "Server action updates read status in database",
        "UI removes colored background from read notifications",
        "Badge count decrements when notification marked read",
        "Typecheck passes",
        "Verify in browser using dev-browser skill"
      ],
      "priority": 5,
      "passes": false,
      "notes": ""
    },
    {
      "id": "US-006",
      "title": "Add notification preferences page",
      "description": "As a user, I want to control which notifications I receive.",
      "acceptanceCriteria": [
        "Add /settings/notifications route",
        "Page shows toggle for each notification type",
        "Preferences save to user_preferences table",
        "Changes take effect immediately",
        "Typecheck passes",
        "Verify in browser using dev-browser skill"
      ],
      "priority": 6,
      "passes": false,
      "notes": ""
    }
  ]
}

Story-by-Story Walkthrough

Focus: Just the data modelRalph implements:
  • Create notifications table migration
  • Add columns: id, userId, type, message, read, createdAt
  • Add index on userId
  • Run migration
Why this size works:
  • Single file: one migration
  • Clear scope: just database
  • Fast verification: migration runs or fails
Commit: feat: add notifications tableprogress.txt update:
US-001: PASS
- Created notifications table with schema
- Added index on userId for query performance
- Migration file: 2024-03-11-add-notifications.ts
Focus: Just the creation logicRalph implements:
  • Create lib/services/notification.ts
  • Implement create() function
  • Add unit tests
  • Export from services index
Why this size works:
  • Single file: one service
  • Clear interface: one public function
  • Testable: unit tests verify behavior
Commit: feat: add notification serviceprogress.txt update:
US-002: PASS
- Created NotificationService in lib/services/notification.ts
- Implemented create(userId, type, message) method
- Added tests for success and error cases
- Service is ready for use by other features
Focus: Just the indicatorRalph implements:
  • Add bell icon to components/Header.tsx
  • Query for unread count
  • Display badge with count
  • Style badge to match design system
Why this size works:
  • Single component modification
  • Simple query (just count)
  • Visual verification with dev-browser
Commit: feat: add notification bell to headerprogress.txt update:
US-003: PASS
- Added bell icon to Header component
- Displays unread count badge
- Used existing Badge component with count prop
- Verified bell appears in browser with correct styling
Focus: Just the display panelRalph implements:
  • Create components/NotificationPanel.tsx
  • Fetch recent notifications (limit 10)
  • Render list with message, icon, timestamp
  • Style unread vs read differently
  • Add click-outside-to-close behavior
Why this size works:
  • Single new component
  • Read-only (no mutations)
  • Self-contained UI logic
Commit: feat: add notification dropdown panelprogress.txt update:
US-004: PASS
- Created NotificationPanel component
- Shows 10 most recent notifications
- Used Popover component for dropdown behavior
- Unread notifications have light blue background
- Verified dropdown opens/closes correctly in browser
Focus: Just the interactionRalph implements:
  • Create server action markNotificationRead(id)
  • Add onClick handler to notification items
  • Optimistically update UI
  • Decrement badge count
Why this size works:
  • Single interaction flow
  • One server action
  • Clear success criteria
Commit: feat: add mark-as-read functionalityprogress.txt update:
US-005: PASS
- Created markNotificationRead server action
- Clicking notification marks it as read
- UI updates optimistically for instant feedback
- Badge count decrements correctly
- Verified interaction in browser
Focus: Just the settings UIRalph implements:
  • Create app/settings/notifications/page.tsx
  • Query user preferences from database
  • Render toggles for each notification type
  • Create server action for saving preferences
  • Add to settings navigation
Why this size works:
  • Single page component
  • Standard CRUD pattern
  • Independent from other stories
Commit: feat: add notification preferences pageprogress.txt update:
US-006: PASS
- Created /settings/notifications page
- Toggle switches for each notification type
- Preferences save to user_preferences table
- Changes apply immediately
- Verified page in browser, all toggles work

<promise>COMPLETE</promise>

What Made This Work

Each story was small enough to complete in one iteration:US-001: One migration file US-002: One service file + tests US-003: One component modification US-004: One new component US-005: One interaction + server action US-006: One page componentNone required touching more than 2-3 files.

Common Mistakes to Avoid

Don’t combine multiple layers in one story:Bad: “Add notifications table and UI” Good: Separate into US-001 (table) and US-003/004 (UI)Don’t make stories depend on future stories:Bad: US-003 (display) before US-001 (schema) Good: Schema first, then everything elseDon’t use vague acceptance criteria:Bad: “Notifications work correctly” Good: “Bell icon shows unread count badge”

Adapting This Pattern

Use this breakdown strategy for any complex feature:
  1. Authentication system: Schema → Middleware → Login UI → Session handling
  2. Search feature: Schema → Indexing → API endpoint → Search UI → Filters
  3. File uploads: Schema → Upload service → UI component → Progress tracking
The pattern is always: Data → Logic → Display → Interactions
The notification system example demonstrates production patterns for breaking down features. Use it as a reference when creating your own prd.json files.

Build docs developers (and LLMs) love