Last updated: Aug 4, 2025, 11:26 AM UTC

Feature Validation Standards Guide

Status: Complete
Category: Critical Development Standards
Version: 1.0
Based On: V4 "Real Working Features" Philosophy


The Ultimate Test

"Show me the campaign you created"
V3 Answer: "Here's the UI where you would create it"
V4 Answer: "Here's campaign 18d63b82-5dcd-4e56-a066-8d1bd7a3a476 in the database"

Only V4 passes. This guide ensures you build V4 quality.


Table of Contents

  1. Core Philosophy
  2. Definition of "Working"
  3. Database-First Development
  4. Real Integration Testing
  5. Success Metrics
  6. Validation Protocols
  7. Common Anti-Patterns
  8. Implementation Checklist

Core Philosophy

Working > Perfect

The V4 Success Formula:

Database First β†’ Real APIs β†’ Real Integrations β†’ Real Data β†’ Real Value

Key Principles

  1. Real IDs Beat Mock Data: Every feature creates queryable database records
  2. Integration Errors Are Success: They prove the system is real
  3. Test with External Services Immediately: Discover real issues early
  4. Every Feature Needs a Database Table: No table = No feature
  5. Can a Customer Use It?: The only question that matters

Definition of "Working"

What "Working" Means

interface WorkingFeature {
  // MANDATORY: All must be true
  database: {
    recordsCreated: boolean;      // Real records exist
    recordsQueryable: boolean;    // Can SELECT and verify
    recordsPersistent: boolean;   // Survives restart
    recordsHaveRealIds: boolean;  // UUIDs, not "mock-123"
  };
  
  api: {
    endpointResponds: boolean;    // Returns real data
    createsRealData: boolean;     // Not mock responses
    handlesErrors: boolean;       // Graceful failures
    returnsRealIds: boolean;      // Traceable IDs
  };
  
  integration: {
    externalServiceCalled: boolean;  // Actually connects
    realResponseReceived: boolean;   // Not mocked
    errorsAreReal: boolean;         // "Domain not verified" = good!
    dataFlowsThrough: boolean;      // End-to-end works
  };
  
  user: {
    canDemonstrateFeature: boolean;  // Show actual result
    dataIsVerifiable: boolean;       // Can query and confirm
    valueIsDelivered: boolean;       // Solves real problem
  };
}

Concrete Examples

NOT Working (V3 Style)

// Returns mock data
async function createCampaign(data) {
  return { 
    id: "mock-campaign-123",
    status: "created" 
  };
}

WORKING (V4 Style)

// Creates real database record
async function createCampaign(data) {
  const result = await db.query(
    'INSERT INTO campaigns (name, config) VALUES ($1, $2) RETURNING id',
    [data.name, data.config]
  );
  return { 
    id: result.rows[0].id, // Real UUID: "18d63b82-5dcd-4e56-a066-8d1bd7a3a476"
    status: "created" 
  };
}

// Proof it works:
// SELECT * FROM campaigns WHERE id = '18d63b82-5dcd-4e56-a066-8d1bd7a3a476';
// Returns actual data!

Database-First Development

The V4 Approach: Create Before You Need

-- STEP 1: Create tables FIRST (before any UI)
CREATE TABLE campaigns (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  organization_id UUID NOT NULL,
  name VARCHAR(255) NOT NULL,
  status VARCHAR(50) DEFAULT 'draft',
  config JSONB DEFAULT '{}',
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE contacts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  organization_id UUID NOT NULL,
  email VARCHAR(255) NOT NULL,
  first_name VARCHAR(100),
  last_name VARCHAR(100),
  tags TEXT[] DEFAULT '{}',
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE email_deliveries (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  campaign_id UUID REFERENCES campaigns(id),
  contact_id UUID REFERENCES contacts(id),
  status VARCHAR(50),
  delivered_at TIMESTAMP,
  opened_at TIMESTAMP,
  clicked_at TIMESTAMP
);

Validation: Tables Exist Before Features

// MANDATORY: Run before starting feature development
async function validateDatabaseReady(): Promise<boolean> {
  const requiredTables = [
    'campaigns',
    'contacts', 
    'email_deliveries',
    'organizations',
    'users'
  ];
  
  for (const table of requiredTables) {
    const exists = await db.query(
      "SELECT EXISTS (SELECT FROM pg_tables WHERE tablename = $1)",
      [table]
    );
    
    if (!exists.rows[0].exists) {
      throw new Error(`Missing required table: ${table}`);
    }
  }
  
  return true;
}

Real Integration Testing

Test with Real Services Immediately

// ❌ WRONG: Mock service for "later"
class EmailService {
  async send(email) {
    console.log('Would send email:', email);
    return { success: true, messageId: 'mock-123' };
  }
}

// βœ… RIGHT: Real service from day one
class EmailService {
  async send(email) {
    try {
      const response = await fetch('https://api.postmarkapp.com/email', {
        method: 'POST',
        headers: {
          'X-Postmark-Server-Token': process.env.POSTMARK_TOKEN,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(email)
      });
      
      const result = await response.json();
      
      // Real error? GOOD! We learned something
      if (result.ErrorCode) {
        console.log('Integration insight:', result.Message);
        // "Sender signature not verified" tells us what to fix!
      }
      
      return result;
    } catch (error) {
      // Real integration errors guide next steps
      console.log('Real issue discovered:', error);
      throw error;
    }
  }
}

Integration Validation Checklist

interface IntegrationValidation {
  service: string;
  checks: {
    canConnect: boolean;        // Service responds
    authWorks: boolean;         // Credentials valid
    canSendData: boolean;       // API accepts our format
    receivesResponse: boolean;  // Get real response
    errorsInformative: boolean; // Errors guide fixes
  };
  
  // Document real responses for proof
  sampleResponse?: {
    success?: any;
    error?: any;
  };
}

// Example validation result
const postmarkValidation: IntegrationValidation = {
  service: 'Postmark',
  checks: {
    canConnect: true,
    authWorks: true,
    canSendData: true,
    receivesResponse: true,
    errorsInformative: true
  },
  sampleResponse: {
    error: {
      ErrorCode: 406,
      Message: "Sender signature not verified"
      // This real error taught us we need domain verification!
    }
  }
};

Success Metrics

Quantitative Validation

class FeatureValidator {
  async validate(featureName: string): Promise<ValidationReport> {
    const report = {
      feature: featureName,
      timestamp: new Date().toISOString(),
      checks: {},
      evidence: {}
    };
    
    // 1. Database Records Exist
    const recordCount = await db.query(
      'SELECT COUNT(*) FROM campaigns WHERE created_at > NOW() - INTERVAL \'1 hour\''
    );
    report.checks.hasRealData = recordCount.rows[0].count > 0;
    
    // 2. API Endpoints Work
    const apiTest = await fetch('/api/campaigns');
    report.checks.apiResponds = apiTest.ok;
    report.evidence.apiResponse = await apiTest.json();
    
    // 3. Real IDs Generated
    const campaign = await createTestCampaign();
    report.checks.generatesRealIds = isValidUUID(campaign.id);
    report.evidence.sampleId = campaign.id;
    
    // 4. Data Persists
    const retrieved = await db.query(
      'SELECT * FROM campaigns WHERE id = $1',
      [campaign.id]
    );
    report.checks.dataPersists = retrieved.rows.length > 0;
    
    // 5. User Can Demonstrate
    report.checks.userCanDemo = Object.values(report.checks)
      .every(check => check === true);
    
    return report;
  }
}

Qualitative Validation

## Feature Validation Report

**Feature**: Campaign Creation
**Date**: 2025-08-03
**Validator**: Development Team

### Can a customer use it? βœ… YES

**Evidence**:
1. Created campaign with ID: `18d63b82-5dcd-4e56-a066-8d1bd7a3a476`
2. Campaign exists in database (verified via SELECT)
3. API returns real campaign data
4. Email integration attempted (got real error response)
5. Contact import successful (5 contacts added)

### Real IDs Generated:
- Campaign: `18d63b82-5dcd-4e56-a066-8d1bd7a3a476`
- Contact: `a7f3b291-8c54-4e89-b234-567890123456`
- User: `f855a22c-beed-4ed5-a14c-e7cabd2187f3`

### Integration Status:
- βœ… Database: Connected and storing data
- ⚠️ Postmark: Connected but needs domain verification
- βœ… n8n: Workflows deployable via API
- βœ… Analytics: Returning real metrics

Validation Protocols

Daily Validation Routine

#!/bin/bash
# Daily feature validation script

echo "🎯 Daily Feature Validation"
echo "=========================="

# 1. Check database has real data
echo "1. Database Check:"
psql $DATABASE_URL -c "SELECT COUNT(*) as campaigns FROM campaigns;"
psql $DATABASE_URL -c "SELECT COUNT(*) as contacts FROM contacts;"

# 2. Test API endpoints
echo "2. API Check:"
curl -X GET http://localhost:3000/api/campaigns | jq .
curl -X GET http://localhost:3000/api/analytics | jq .

# 3. Verify specific IDs still exist
echo "3. Known ID Check:"
psql $DATABASE_URL -c "SELECT id, name FROM campaigns WHERE id = '18d63b82-5dcd-4e56-a066-8d1bd7a3a476';"

# 4. Test create operation
echo "4. Create Test:"
curl -X POST http://localhost:3000/api/campaigns \
  -H "Content-Type: application/json" \
  -d '{"name":"Daily Test Campaign"}' | jq .

echo "βœ… Validation Complete"

Per-Feature Validation

// Run for EVERY feature before marking complete
async function validateFeatureComplete(feature: string) {
  const validations = [
    checkDatabaseRecords,
    checkApiEndpoints,
    checkIntegrations,
    checkUserFlow,
    checkErrorHandling
  ];
  
  const results = await Promise.all(
    validations.map(v => v(feature))
  );
  
  const allPassed = results.every(r => r.passed);
  
  if (!allPassed) {
    const failures = results.filter(r => !r.passed);
    throw new Error(
      `Feature ${feature} validation failed:\n` +
      failures.map(f => `- ${f.reason}`).join('\n')
    );
  }
  
  // Generate proof document
  await generateValidationProof(feature, results);
  
  return true;
}

Common Anti-Patterns

Anti-Pattern 1: Mock-First Development

Wrong: Build with mocks, plan to add real data "later"
Right: Connect to real database from minute one
Why: "Later" never comes, mocks hide real issues

Anti-Pattern 2: Perfect Infrastructure First

Wrong: Spend days on perfect architecture with no features
Right: Create working features with simple architecture
Why: Working beats perfect every time

Anti-Pattern 3: UI Without Database

Wrong: Build beautiful UI that doesn't persist data
Right: Create database tables before UI
Why: UI without data is just a picture

Anti-Pattern 4: Avoiding External Services

Wrong: "We'll integrate Postmark after everything else works"
Right: Integrate Postmark in first iteration
Why: Integration errors teach valuable lessons early

Anti-Pattern 5: Untraceable Success Claims

Wrong: "The feature works!" (no evidence)
Right: "Campaign 18d63b82 exists in database" (provable)
Why: Concrete IDs are undeniable proof


Implementation Checklist

Before Starting Any Feature

  • Database table created
  • Migration script written and run
  • Sample data inserted for testing
  • Direct SQL query confirms table works

During Feature Development

  • API endpoint creates real records
  • Generated IDs are real UUIDs
  • External service integration attempted
  • Errors logged and learned from
  • Data persistence verified

Before Marking Complete

  • Specific ID documented as proof
  • Database query shows real data
  • API returns actual records
  • User can demonstrate feature
  • Integration errors documented

Validation Evidence Required

  • Screenshot of database query result
  • API response with real ID
  • Integration attempt log (success or error)
  • User demonstration video/screenshot
  • Validation script output

Quick Validation Commands

# Prove your feature works with these commands:

# 1. Show me the record
psql $DATABASE_URL -c "SELECT * FROM [table] WHERE id = '[your-uuid]';"

# 2. Call the API
curl http://localhost:3000/api/[endpoint]/[your-uuid]

# 3. Count real records
psql $DATABASE_URL -c "SELECT COUNT(*) FROM [table] WHERE created_at > NOW() - INTERVAL '1 day';"

# 4. Show integration attempts
grep "Postmark\|n8n\|Stripe" logs/app.log | tail -20

# 5. Demonstrate persistence (restart and check)
docker-compose restart
psql $DATABASE_URL -c "SELECT * FROM [table] WHERE id = '[your-uuid]';"

Success Criteria

A feature is ONLY complete when:

  1. Real Database Records

    • Query returns actual data
    • IDs are UUIDs, not mocks
  2. Working API

    • Endpoints return real data
    • Errors are handled gracefully
  3. Integration Attempted

    • External service was called
    • Real response (error or success) received
  4. User Can Demo

    • "Show me X" has a concrete answer
    • Data survives restart
  5. Evidence Documented

    • Specific IDs recorded
    • Validation output saved

Final Wisdom

"Working software is the primary measure of progress" - Agile Manifesto

This guide ensures you build WORKING software, not beautiful mockups.

Remember:

  • Real IDs > Mock data
  • Database records > UI promises
  • Integration errors > No integration
  • Concrete evidence > "Trust me it works"
  • Customer value > Developer comfort

Based on V4's breakthrough realization: Features without real data are just expensive mockups. Build real value from day one.