lantern

component-dfaas

Component: DFAAS - Demand Forecasting as a Service

Type: Next.js 14 Application
Category: Business Intelligence / Forecasting
Status: Reference Implementation
Repository: amjad-ai-projects/DFAAS
Case: task-afcd480a-d6c8-4c76-8104-9d8d75323777


What It Does

DFAAS is an enterprise demand planning platform for high-tech electronics distribution. It provides:

  • Statistical Forecasting: Multi-method forecast generation with confidence intervals
  • Scenario Planning: What-if analysis with baseline/optimistic/pessimistic scenarios
  • Consensus Workflow: Collaborative forecast adjustment and locking
  • Exception Management: Auto-detection and triage of forecast anomalies
  • Conversational AI: Claude-powered assistant with live system state context

Design Philosophy: "Autopilot First" - system runs automatically, humans manage exceptions not routine.


Why It Exists

Demand forecasting is a complex domain requiring:

  • Statistical rigor (algorithms, confidence intervals, accuracy metrics)
  • Human judgment (market knowledge, promotional intelligence)
  • Collaboration (consensus across stakeholders)
  • Exception handling (anomalies that break the model)

DFAAS demonstrates how to build an AI-augmented forecasting platform where the conversational interface has live awareness of system state.


Technology Stack

Layer Technology
Framework Next.js 14 (App Router)
Language TypeScript
Styling Tailwind CSS
AI Claude API (claude-sonnet-4-20250514)
State React useState (session-scoped)
Data In-memory generated (demo mode)
Deployment Vercel / Docker

Key Dependencies

{
  "@anthropic-ai/sdk": "latest",
  "next": "14.x",
  "react": "18.x",
  "tailwindcss": "3.x",
  "lucide-react": "icons",
  "zod": "schema validation"
}

Architecture

Application Structure

apps/web/
├── app/                          # Next.js App Router
│   ├── api/chat/route.ts         # Claude API endpoint
│   ├── dashboard/                # KPI overview
│   ├── forecast/                 # Forecasting tools
│   │   ├── page.tsx              # Statistical forecast
│   │   ├── scenarios/            # Scenario planning
│   │   └── consensus/            # Lock workflow
│   ├── exceptions/               # Exception workbench
│   ├── data/                     # Master data management
│   ├── config/                   # Hierarchies, policies
│   ├── admin/                    # User management
│   ├── chat/page.tsx             # Conversational UI
│   └── setup/page.tsx            # Onboarding wizard
├── lib/
│   ├── data/                     # Data layer
│   │   ├── schema.ts             # Entity schemas + UDFs
│   │   ├── master-data.ts        # Items, locations
│   │   ├── demand-history.ts     # Historical + anomalies
│   │   ├── forecasts.ts          # Forecast generation
│   │   ├── notifications.ts      # Proactive alerts
│   │   ├── change-tracking.ts    # Delta detection
│   │   └── documentation.ts      # Platform docs
│   └── instrumentation/          # Logging, health
└── components/                   # Reusable UI

Core Algorithms

Forecasting Formula

The statistical forecast is computed as:

StatisticalForecast = BaseQuantity 
  × SeasonalFactor 
  × RegionalFactor 
  × ChannelFactor 
  × YoYGrowth 
  × (0.9 + Random × 0.2)  // ±10% noise

Factor Tables

Velocity Class → Base Quantity

Class Range Description
A 50-200 Fast movers
B 20-100 Medium velocity
C 5-35 Slow movers
D 1-11 Long tail

Region → Multiplier

Region Factor Rationale
West 1.25 Tech hub concentration
Northeast 1.15 Dense urban markets
Southwest 1.10 Growth markets
Southeast 1.00 Baseline
Midwest 0.90 Stable, lower volume

Channel → Multiplier

Channel Factor Rationale
E-commerce 1.30 High growth, flash sales
Retail 1.00 Baseline
Wholesale 0.80 Bulk, lower margin
Enterprise 0.60 Contracted, predictable

Seasonality Patterns

52-week multiplier arrays per category capturing:

  • Holiday Peak (W44-52): 2x-3.5x lift
  • Back-to-School (W26-35): 1.5x-2x for laptops/tablets
  • Post-Holiday Slump (W1-8): 0.6x-0.8x
  • Tech Launch Season (W36-44): Category-specific spikes
// Example: Gaming category (highest holiday volatility)
const gaming = [
  0.9, 0.85, 0.8, 0.85, 0.9, 0.9, 0.95, 0.95,  // W1-8
  1.0, 1.0, 1.0, 1.0, 0.95, 0.95, 0.95, 0.95,  // W9-16
  1.0, 1.0, 1.0, 1.05, 1.1, 1.1, 1.05, 1.0,    // W17-24
  1.0, 1.0, 1.05, 1.1, 1.1, 1.05, 1.0, 1.0,    // W25-32
  1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8,      // W33-40
  2.0, 2.3, 2.6, 3.0, 3.5, 3.2, 2.5, 1.8,      // W41-48 (BLACK FRIDAY)
  1.4, 1.2, 1.0, 0.95                           // W49-52
]

Confidence Intervals

// Confidence decays over forecast horizon
confidence = BaseMethodAccuracy - (weekOffset × 0.008) ± random(0.1)

// Bounds calculation
errorMargin = (1 - confidence) × 1.5
lowerBound = forecast × (1 - errorMargin)
upperBound = forecast × (1 + errorMargin)

Forecast Methods

Method Accuracy Suitable For
ml-ensemble 82% Year-round stable
prophet 80% Holiday, seasonal
exponential-smoothing 78% General purpose
arima 75% Trend + seasonal
seasonal-naive 72% Strong patterns
moving-average 70% Baseline fallback

Method selection is automatic based on item's seasonality attribute.


Data Model

Entity Schemas

ItemSchema (Products/SKUs)

interface ItemSchema {
  // Identity
  id: string
  sku: string
  name: string
  
  // Hierarchy
  categoryId: string
  subcategoryId?: string
  brandId?: string
  divisionId?: string
  
  // Classification
  status: 'active' | 'new' | 'discontinued' | 'seasonal' | 'on-hold'
  velocityClass: 'A' | 'B' | 'C' | 'D' | 'X'
  lifecycleStage: 'introduction' | 'growth' | 'maturity' | 'decline'
  
  // Forecasting
  forecastMethod?: 'statistical' | 'ml' | 'manual' | 'hybrid'
  seasonalityPattern?: 'none' | 'weekly' | 'monthly' | 'quarterly' | 'annual'
  includeInForecast: boolean
  
  // Extensibility
  udfValues: UDFValue[]  // Unlimited custom fields
}

ForecastTransactionSchema

interface ForecastTransactionSchema {
  // Keys
  itemId: string
  locationId: string
  forecastDate: string
  
  // Forecast Layers
  statisticalForecast: number    // Algorithm output
  adjustedForecast?: number      // Planner modifications
  consensusForecast?: number     // Team agreement
  finalForecast?: number         // Locked for planning
  
  // Confidence
  confidenceLevel?: number
  lowerBound?: number
  upperBound?: number
  
  // Workflow
  status: 'draft' | 'reviewed' | 'approved' | 'locked' | 'superseded'
  lockedAt?: string
  lockedBy?: string
  
  // Scenarios
  scenarios: {
    baseline: number
    optimistic: number
    pessimistic: number
    promotional?: number
  }
}

UDF System

User Defined Fields allow unlimited extensibility:

type UDFDataType = 
  | 'string' | 'number' | 'boolean' 
  | 'date' | 'datetime'
  | 'currency' | 'percentage'
  | 'email' | 'url' | 'phone'
  | 'json' | 'array' | 'enum'

interface UDFDefinition {
  id: string
  name: string
  displayName: string
  dataType: UDFDataType
  entityType: 'item' | 'location' | 'transaction' | 'forecast'
  isRequired: boolean
  isSearchable: boolean
  isFilterable: boolean
  validationRules?: UDFValidationRule[]
  enumOptions?: string[]  // For dropdowns
}

Exception Detection

Exception Types

Type Severity Trigger
stockout-risk Critical Inventory < safety stock
accuracy-drop Critical/High Accuracy < 65%
bias-alert High Bias > ±8%
demand-spike High/Medium Actual > forecast × 1.5
demand-drop Medium Actual < forecast × 0.5
consensus-needed High Unlocked near horizon
new-item Low < 8 weeks history
volatility Medium High CV
forecast-override Low Manual change detected

Impact Scoring

Exceptions are scored 0-100 to determine surfacing priority:

function calculateImpactScore(anomaly) {
  let score = 0
  
  // 40% weight: Severity
  score += { critical: 40, high: 30, medium: 20, low: 10 }[severity]
  
  // 30% weight: Deviation magnitude
  score += Math.min(Math.abs(deviation) * 5, 30)
  
  // 15% weight: Type factor
  if (type === 'stockout') score += 15
  else if (type === 'spike' && deviation > 3) score += 12
  
  // 15% weight: Recency
  if (daysSince <= 7) score += 15
  else if (daysSince <= 14) score += 10
  
  return Math.min(score, 100)
}

Auto-Resolution Rules

function canAutoResolve(anomaly): boolean {
  // Low severity + small deviation
  if (severity === 'low' && Math.abs(deviation) < 2) return true
  
  // Historical (>4 weeks old, non-critical)
  if (daysSince > 28 && severity !== 'critical') return true
  
  // Holiday season spikes (expected)
  if (type === 'spike' && weekNumber >= 48 && severity !== 'critical') return true
  
  return false
}

Live Context Assembly [fence-candidate:context-builder]

This is the key pattern for conversational AI integration.

The chat API builds a dynamic system prompt at request time:

// api/chat/route.ts
function buildSystemPrompt(): string {
  // 1. Pull live metrics
  const kpis = getDashboardKPIs()
  const accuracyByCategory = getAccuracyByCategory()
  const accuracyByRegion = getAccuracyByRegion()
  const exceptions = generateExceptions()
  
  // 2. Filter to actionable items
  const openExceptions = exceptions.filter(e => 
    e.status === 'open' || e.status === 'in-progress'
  )
  const criticalExceptions = exceptions.filter(e => 
    e.severity === 'critical' && e.status === 'open'
  )
  
  // 3. Assemble context sections
  return `You are an AI assistant for DFAAS...

## Current System State

### Business Overview
- **Total Items**: ${dataSummary.totalItems.toLocaleString()}
- **Total Locations**: ${dataSummary.totalLocations}
- **Categories**: ${categories.map(c => c.name).join(', ')}

### Current KPIs
- **Forecast Accuracy**: ${kpis.forecastAccuracy.value}% (Target: ${kpis.forecastAccuracy.target}%)
- **Forecast Bias**: ${kpis.avgBias.value}%
- **Open Exceptions**: ${openExceptions.length} (${criticalExceptions.length} critical)

### Accuracy by Category
${accuracyByCategory.map(c => 
  \`- ${c.category}: ${c.accuracy}% (${c.trend})\`
).join('\n')}

### Top Open Exceptions
${openExceptions.slice(0, 10).map(e => 
  \`- [${e.severity.toUpperCase()}] ${e.type}: ${e.entityName}\`
).join('\n')}

## Quick Reference
${quickReference.resolveException}
${quickReference.runForecast}
...

## Role-Specific Guidance
${roleGuidance[userRole]}

## Platform Documentation
${platformDocumentation}
`
}

Context Sections Pattern

Section Purpose Update Frequency
System State Live KPIs, counts Every request
Accuracy Metrics By dimension Every request
Open Exceptions Actionable items Every request
Quick Reference How-to snippets Static
Role Guidance Workflow by role Static
Documentation Full platform docs Static

Fence Candidates for MCP

# Proposed fences to replicate this pattern

context-snapshot:
  description: "Build live system state summary for AI context"
  params:
    - include_kpis: boolean
    - include_exceptions: boolean  
    - exception_limit: number
    - include_accuracy: boolean
  returns: markdown

role-guidance:
  description: "Get workflow guidance for a specific role"
  params:
    - role: enum[planner, analyst, manager, admin]
  returns: markdown

quick-reference:
  description: "Get how-to snippet for common task"
  params:
    - task: enum[resolve-exception, run-forecast, lock-forecast, ...]
  returns: markdown

exception-summary:
  description: "Get prioritized exception list"
  params:
    - severity: enum[critical, high, medium, low, all]
    - limit: number
    - include_auto_resolved: boolean
  returns: structured

Workflows

Forecast Lifecycle

┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│  Statistical │ -> │   Adjusted   │ -> │  Consensus   │ -> │    Locked    │
│   Forecast   │    │   Forecast   │    │   Forecast   │    │   Forecast   │
└──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘
   Algorithm          Planner             Team Review         Final for
   Generated          Judgment            Agreement           Planning

Lock Mechanics

// First 4 weeks: 80% lock probability (near-term)
// Weeks 5-8: 50% lock probability (medium-term)  
// Weeks 9+: Unlocked (subject to revision)

if (weekIndex < 4) {
  lockProbability = 0.8
} else if (weekIndex < 8) {
  lockProbability = 0.5
} else {
  lockProbability = 0
}

Exception Resolution

DetectClassifyScoreRoute
                      ↓
         ┌───────────┴───────────┐
         ↓                       ↓
   Auto-Resolve            Human Review
   (low impact)            (high impact)
         ↓                       ↓
      Archive              ActionResolve

UI Components

Chat Interface

interface Message {
  id: string
  role: 'user' | 'assistant'
  content: string
  artifacts?: Artifact[]        // Structured data panels
  proposedActions?: ProposedAction[]  // Executable suggestions
  timestamp: Date
}

interface Artifact {
  type: 'grid' | 'chart' | 'list' | 'summary'
  title?: string
  data: any
}

interface ProposedAction {
  action_id: string
  type: string  // 'create_override' | 'run_forecast' | ...
  description: string
  details: any
  requires_confirmation: boolean
}

Suggested Queries (Prompt Starters)

const suggestedQueries = [
  'Show me items with forecast accuracy below 70%',
  'What are the top 10 exceptions this week?',
  'Run forecast for Northeast region',
  'Add 15% uplift for Beverages in Q2',
  'Compare baseline vs consensus scenario',
  'Why is bias high in Electronics?',
]

Configuration

Environment Variables

# Required
ANTHROPIC_API_KEY=sk-ant-...

# Optional
NODE_ENV=development|production

Onboarding Wizard Steps

  • welcome - Introduction
  • company - Company profile (name, industry, timezone, fiscal year)
  • branding - Logo + color theme (optional)
  • authentication - SSO providers (Microsoft, Google, Email)
  • hierarchies - Product/Location hierarchy definition
  • master-data - CSV upload for items/locations
  • history - Demand history upload (52+ weeks)
  • forecasting - Horizon, frequency, auto-forecast toggle
  • users - Team invitations + role assignment
  • review - Summary + launch

Accuracy Metrics

Calculation by Dimension

// Base accuracy: 76%
let accuracy = 76

// Category adjustments
if (category === 'accessories') accuracy += 5   // Very predictable
if (category === 'networking') accuracy += 4    // Stable B2B
if (category === 'smartphones') accuracy -= 3   // Tech cycles
if (category === 'gaming') accuracy -= 5        // Most volatile

// Channel adjustments  
if (channel === 'retail') accuracy += 2
if (channel === 'ecommerce') accuracy -= 3      // Flash sales
if (channel === 'enterprise') accuracy += 3    // Contracted

// Region adjustments
if (region === 'west') accuracy += 1           // Tech hub
if (region === 'midwest') accuracy += 2        // Stable

KPI Definitions

Metric Formula Target
Forecast Accuracy 100 - WMAPE 80%
Forecast Bias Mean(Actual - Forecast) / Mean(Actual) 0%
MAPE Mean( Actual - Forecast
Consensus Locked Locked / Total (next 4 weeks) 95%

Data Volumes (Demo)

Entity Count
Categories 12
Subcategories 68
Items (SKUs) ~700
Locations 28
Regions 5
Channels 4
History 104 weeks (2024-2025)
Forecast 52 weeks (2026)

Related Patterns

  • Live Context Assembly: Dynamic system prompt construction
  • Impact Scoring: Prioritization algorithm for exceptions
  • Auto-Resolution: Rules-based exception handling
  • Confidence Decay: Forecast reliability over time horizon
  • Scenario Modeling: What-if analysis with factor adjustments

Reconstruction Notes

To rebuild DFAAS from this spec:

  • Data Layer First: Implement schema.ts with UDF support
  • Forecast Engine: Port the formula + seasonality arrays
  • Exception Detection: Implement scoring + auto-resolve rules
  • Context Builder: The buildSystemPrompt() function is key
  • UI Last: Standard Next.js patterns throughout

The conversational interface's value comes from the live context assembly - ensure the AI always knows current system state.


Slots

North

slots:
- slug: beye-ai-one-pager
  context:
  - Linking DFAAS to parent Beye AI documentation

South

slots:
- slug: fence-conversational-context
  context:
  - Linking fence spec to its source implementation

East

slots:
- slug: dfaas-wanderland-mapping
  context:
  - Linking component spec to its Wanderland implementation mapping

West

slots: []

Provenance

Document

  • Status: 🔴 Unverified

Changelog

  • 2026-01-25 19:14: Node created by mcp - Creating component documentation for DFAAS demand forecasting application - extracting patterns for Wanderland port, especially the live context assembly for conversational AI